zoukankan      html  css  js  c++  java
  • 2017北京国庆刷题Day7 morning

    期望得分:100+0+100=200

    实际得分:100+20+0=120

    离散化搞搞

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define N 100001
    int a[N],b[N];
    bool vis[N];
    void read(int &x)
    {
        x=0;  char c=getchar();
        while(!isdigit(c))  c=getchar(); 
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    int main()
    {
        freopen("del.in","r",stdin);
        freopen("del.out","w",stdout);
        int n,k;
        read(n); read(k);
        for(int i=1;i<=n;i++) read(a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        int tot=unique(b+1,b+n+1)-b-1;
        for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
        int cnt1=0,cnt2=0;
        for(int i=1;i<=n;i++)
            if(!vis[a[i]]) vis[a[i]]=true,cnt1++;
            else cnt2++;
        if(k<=cnt2) printf("%d
    ",cnt1);
        else printf("%d
    ",cnt1-(k-cnt2));
        return 0; 
    }
    View Code

    阅读理解之坑:加冕没有用

    出题人想表达停在那儿,就是不再继续跳吃

    考场上没写出来原因有二:

    1、死磕加冕

    2、怕TLE,写的记忆化,这种题最好先打出裸的dfs

    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    char s[11];
    int mp[11][11];
    bool mp2[11][11],vis[11][11];
    
    int cnt,mx,tot;
    struct node
    {
        int x,y;
    }ans[101];
    
    int dx[4]={-1,-1,1,1};
    int dy[4]={-1,1,1,-1};
    
    void init()
    {
        for(int i=1;i<=10;i++)
        {
            scanf("%s",s+1);
            for(int j=1;j<=10;j++) mp[i][j]=s[j]-'0';
        }
        for(int i=1;i<=10;i++)
        {
            scanf("%s",s+1);
            for(int j=1;j<=10;j++) mp2[i][j]=s[j]-'0';
        }
    }
    
    bool inmap(int x,int y)
    {
        return (!(x<=0) && !(x>10) && !(y<=0) && !(y>10));
    }
    
    bool empty(int x,int y)
    {
        return !mp[x][y];
    }
    
    bool jump(int x,int y)
    {
        if(!inmap(x,y)) return false;
        return mp[x][y]==2;
    }
    
    bool have(int x,int y)
    {
        return vis[x][y];
    }
    
    void update(int i,int j)
    {
        if(cnt>mx)
        {
            mx=cnt; tot=1;
            ans[1].x=i; ans[1].y=j;
        }
        else if(cnt==mx) 
        {
            ans[++tot].x=i; ans[tot].y=j;
        }
    }
    
    void dfs(int x,int y,int sx,int sy)
    {
        vis[x][y]=true;
        for(int i=0;i<4;i++)
            if(jump(x+dx[i],y+dy[i]) && inmap(x+dx[i]+dx[i],y+dy[i]+dy[i]) && empty(x+dx[i]+dx[i],y+dy[i]+dy[i]))
            {
                if(have(x+dx[i],y+dy[i]) || have(x+dx[i]+dx[i],y+dy[i]+dy[i]) ) continue;
                cnt++; update(sx,sy);
                dfs(x+dx[i]+dx[i],y+dy[i]+dy[i],sx,sy);
                cnt--;
            }
        vis[x][y]=false;
    }
    
    void dfs2(int x,int y,int sx,int sy)
    {
        vis[x][y]=true;
        for(int d=0;d<4;d++)
        {
            int nx=x,ny=y;
            for(int i=1;i<=10;i++)
            {
                nx+=dx[d]; ny+=dy[d];
                if(!inmap(nx,ny)) break;
                if(mp[nx][ny]==1) break;
                if(!jump(nx,ny)) continue;
                if(have(nx,ny)) continue;
                vis[nx][ny]=true;
                int nnx=nx,nny=ny;
                for(int j=1;j<=10;j++)
                {
                    nnx+=dx[d]; nny+=dy[d];
                    if(!inmap(nnx,nny)) break;
                    if(!empty(nnx,nny)) break;
                    if(have(nnx,nny)) continue;
                    cnt++;  update(sx,sy);
                    dfs2(nnx,nny,sx,sy);
                    cnt--;
                }
                vis[nx][ny]=false;
            }
        }
        vis[x][y]=false;
    }
    
    void solve()
    {
        for(int i=1;i<=10;i++)
            for(int j=1;j<=10;j++)
                if(mp[i][j]==1) 
                {
                    if(!mp2[i][j]) dfs(i,j,i,j);
                    else dfs2(i,j,i,j);
                }
        if(!mx)
        {
            cnt=1;
            for(int i=1;i<=10;i++)
                for(int j=1;j<=10;j++)
                    if(mp[i][j]==1)
                    {
                        if(!mp2[i][j])
                        {        
                            for(int k=0;k<2;k++)
                                if(inmap(i+dx[k],j+dy[k]) && empty(i+dx[k],j+dy[k])) update(i,j);
                        }
                        else
                        {
                            for(int k=0;k<4;k++)
                            {
                                int nx=i,ny=j;
                                for(int l=1;l<=10;l++)
                                {
                                    nx+=dx[k];ny+=dy[k];
                                    if(!inmap(nx,ny)) break;
                                    if(!empty(nx,ny)) break;
                                    update(i,j);
                                }
                            }
                        }
                    }
                    
        }
        printf("%d
    ",tot);
        for(int i=1;i<=tot;i++) printf("(%d,%d)
    ",ans[i].x,ans[i].y);
    }
    int main()
    {
        freopen("chess.in","r",stdin);
        freopen("chess.out","w",stdout);
        init();
        solve();
    }
    View Code

     

    考场上顺退概率DP+拓扑排序,全WA了。。

    正解倒推

    dp[i][j]表示还有i个馅饼没有掉下来,当前还差状态为j的馅饼的期望美味度

    (还差状态为j的馅饼指的是 还有状态为j的馅饼没有吃到)

    枚举当前要掉哪类馅饼

    如果能吃,那就从吃和不吃里选最优解

    如果不能吃,那就直接又后面转移

    所以 状态转移方程(设当前正掉下第l类的馅饼)

    if((j&pre[l])==pre[l]) dp[i][j]+=max(dp[i+1][j],dp[i+1][j|(1<<l-1)]+val[l]);
    else dp[i][j]+=dp[i+1][j];

    因为是期望,不要忘了除n

    最后应该输出dp[0][0]

    代码中因为是从n开始枚举的,所以输出了dp[1][0]

    (感谢cyz020202 指出)

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define K 101
    #define N 16
    
    int bit[N];
    int val[N],pre[N];
    double dp[K+1][1<<N+1];
    
    void read(int &x)
    {
        x=0; int f=1; char c=getchar();
        while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); }
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }
    
    int main()
    {
        freopen("bonus.in", "r", stdin);
        freopen("bonus.out", "w", stdout);
        int k,n,x;
        read(k); read(n);
        bit[0]=1;
        for(int i=1;i<=n;i++) bit[i]=bit[i-1]<<1;
        for(int i=1;i<=n;i++)
        {
            read(val[i]);
            read(x);
            while(x) pre[i]+=bit[x-1],read(x);
        }
        int S=1<<n;
        for(int i=k;i;i--)
            for(int j=0;j<S;j++)
            {
                for(int l=1;l<=n;l++)
                    if((j&pre[l])==pre[l]) dp[i][j]+=max(dp[i+1][j],dp[i+1][j|bit[l-1]]+val[l]);
                    else dp[i][j]+=dp[i+1][j];
                dp[i][j]/=1.0*n;
            }
        printf("%.6lf",dp[1][0]);
    }
    View Code
  • 相关阅读:
    [CF864F]Cities Excursions
    [AGC012F]Prefix Median
    [TC-FindingFriends]Finding Friends
    [TC-HouseProtection]House Protection
    [CTSC2018]假面
    [CF877F]Ann and Books
    [CF509F]Progress Monitoring
    [CF735E/736C]Ostap and Tree
    CF611H New Year and Forgotten Tree
    CF538H Summer Dichotomy
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7647064.html
Copyright © 2011-2022 走看看