• 大白第一章第四节dp例题


    入口

    UVALive - 3882 

    #include<cstdio>
    using namespace std;
    const int N=1e4+5;
    int n,m,k,f[N];
    int main(){
        //f[i]表示第i次要删的数字 
        while(scanf("%d%d%d",&n,&k,&m)==3&&n){
            //1
            //f[1]=0;
            //for(int i=2;i<=n;i++) f[i]=(f[i-1]+k)%i;
            //int ans=(m-k+f[n]+1)%n;
            //2
            //int s=0;
            //for(int i=2;i<=n;i++) s=(s+k)%i;
            //int ans=(m-k+s+1)%n;//这3句话来源于上面 
            //if(ans<=0) ans+=n;
            //printf("%d
    ",ans);
            //3
            int s=0;
            for(int i=2;i<n;i++) s=(s+k)%i;
            s=(s+m)%n;
            printf("%d
    ",s+1);
        }
        return 0;
    }

    UVA - 10635 

    //turn to lis
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=1e5+5;
    int T,cas=1,n,p,q,pa[N],a[N],b[N],c[N];
    inline void LIS(){
        int len;c[len=1]=b[1];
        for(int i=2,pos;i<=q+1;i++){
            if(b[i]>c[len]) c[++len]=b[i];
            else{
                pos=lower_bound(c+1,c+len+1,b[i])-c;
                c[pos]=b[i];
            }
        }
        printf("Case %d: %d
    ",cas,len);
    }
    int main(){
        for(scanf("%d",&T);cas<=T;cas++){
            scanf("%d%d%d",&n,&p,&q);
            for(int i=1;i<=p+1;i++) scanf("%d",&a[i]),pa[a[i]]=i;
            for(int i=1;i<=q+1;i++) scanf("%d",&b[i]),b[i]=pa[b[i]];
            LIS();
        }
        return 0;
    } 
    /*//lcs->TLE 
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int N=1e5+5;
    int T,cas=1,n,p,q,a[N],b[N],f[2][N*10];
    int main(){
        for(scanf("%d",&T);cas<=T;cas++){
            scanf("%d%d%d",&n,&p,&q);
            for(int i=1;i<=p+1;i++) scanf("%d",&a[i]);
            for(int i=1;i<=q+1;i++) scanf("%d",&b[i]);
            memset(f,0,sizeof f);int now=0;
            for(int i=1;i<=p+1;i++){
                now^=1;
                for(int j=1;j<=q+1;j++){
                    if(a[i]==b[j]) f[now][j]=f[now^1][j-1]+1;
                    else f[now][j]=max(f[now][j-1],f[now^1][j]);
                }
            }
            printf("Case %d:%d
    ",cas,f[now][q+1]);
        }
        return 0;
    } */

    UVA - 10891 

    //朴素(AC)
    #include<cstdio>
    #include<cstring>
    //dp(i,j)表示选择[i,j]的子序列,在双方都采取最优策略,先手得分的最大值
    //dp(i,j)=sum(i,j)-min{d(i+1,j)……d(j,j),d(i,j-1)……d(i,i)} 
    #include<algorithm>
    using namespace std;
    const int N=105;
    int n,s[N],f[N][N];
    bool vis[N][N];
    int dp(int x,int y){
        if(vis[x][y]) return f[x][y];
        vis[x][y]=1;
        int m=0;//全部取光(精髓) 
        for(int i=x+1;i<=y;i++) m=min(m,dp(i,y));
        for(int i=x;i<y;i++) m=min(m,dp(x,i));
        return f[x][y]=s[y]-s[x-1]-m;
    }
    int main(){
        while(scanf("%d",&n)==1&&n){
            for(int i=1;i<=n;i++) scanf("%d",&s[i]),s[i]+=s[i-1];
            memset(vis,0,sizeof vis);
            printf("%d
    ",2*dp(1,n)-s[n]);
        }
        return 0;
    } 
    //辅助数组优化
    //f(i,j)=min{d(i,j),d(i+1,j)……d(j,j)}
    //g(i,j)=min{d(i,j),d(i,j-1)……d(i,i)}
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=105;
    int n,a[N],s[N],f[N][N],g[N][N],dp[N][N];
    int main(){
        while(scanf("%d",&n)==1&&n){
            memset(f,0,sizeof f);
            memset(g,0,sizeof g);
            for(int i=1;i<=n;i++) scanf("%d",&a[i]),f[i][i]=g[i][i]=dp[i][i]=a[i];
            for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
            for(int L=1;L<n;L++){
                for(int i=1;i+L<=n;i++){
                    int j=i+L;
                    int m=0;
                    m=min(m,f[i+1][j]);
                    m=min(m,g[i][j-1]);
                    dp[i][j]=s[j]-s[i-1]-m;
                    f[i][j]=min(dp[i][j],f[i+1][j]);
                    g[i][j]=min(dp[i][j],g[i][j-1]);
                }
            }
            printf("%d
    ",2*dp[1][n]-s[n]);
        }
        return 0;
    } 

    UVA - 11825 

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int N=1<<17;
    int n,cas;
    int p[N],cover[N],f[N];
    int main(){
        while(scanf("%d",&n)==1&&n){
            memset(p,0,sizeof p);
            memset(cover,0,sizeof cover);
            for(int i=0,m,x;i<n;i++){
                scanf("%d",&m);
                p[i]=1<<i;
                while(m--) scanf("%d",&x),p[i]|=(1<<x);
            }
            for(int S=0;S<(1<<n);S++){
                cover[S]=0;
                for(int i=0;i<n;i++) if(S&(1<<i)) cover[S]|=p[i];
            }
            //dp transfer equation:
            //f(S)=max{f(S-S0)|S0 belong to S,and cover[S0]==ALL}
            int ALL=(1<<n)-1;f[0]=0;
            for(int S=1;S<(1<<n);S++){
                f[S]=0;
                for(int S0=S;S0;S0=(S0-1)&S){
                    if(cover[S0]==ALL) f[S]=max(f[S],f[S^S0]+1);
                }
            }
            printf("Case %d: %d
    ",++cas,f[ALL]);
        }
        return 0;
    }

    UVA - 10859 

    #include<cstdio>
    #include<cstring>
    #include<vector>
    using namespace std;
    const int N=1005;
    const int M=2000;
    int n,m,T,f[N][N];bool vis[N][N];
    vector<int>graph[N];
    int dp(int i,int j,int fa){
        if(vis[i][j]) return f[i][j];
        vis[i][j]=1;
        int &ans=f[i][j];
        ans=M;
        //1:now point with light
        for(int k=0;k<graph[i].size();k++){
            if(graph[i][k]!=fa){
                ans+=dp(graph[i][k],1,i);
            }
        }
        if(!j&&fa>=0) ans++;//not root
        if(j||fa<0){
        //2:now point without light
            int sum=0;
            for(int k=0;k<graph[i].size();k++){
                if(graph[i][k]!=fa){
                    sum+=dp(graph[i][k],0,i);
                }
            }
            if(fa>=0) sum++;//not root
            ans=min(ans,sum);
        }
        return ans;
    }
    int main(){
        for(scanf("%d",&T);T--;){
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++) graph[i].clear();
            for(int i=0,x,y;i<m;i++){
                scanf("%d%d",&x,&y);
                graph[x].push_back(y);
                graph[y].push_back(x);
            }
            memset(vis,0,sizeof vis);
            int ans=0;
            for(int i=0;i<n;i++){
                if(!vis[i][0]){
                    ans+=dp(i,0,-1);
                }
            }
            //ans=Ma+b;beacause DAG
            printf("%d %d %d
    ",ans/M,m-ans%M,ans%M);
        }
        return 0;
    }

    UVALive - 3983 

    #include<cstdio>
    using namespace std;
    const int N=1e5+5;
    int T,c,n,x[N],y[N];
    int dist2origin[N],total_dist[N],total_wight[N];
    int q[N],f[N];
    inline int ABS(int x){
        return x>0?x:-x;
    }
    //dp[i]=min{dp[j]+dist2origin[j+1]+dist[j+1,i]+dist2origin[i]|j<=i,w[j+1,i]<=c}
    //==>min{dp[j]+dist2origin[j+1]-total_dist[j+1]}+total_dist[i]+dist2origin[i]
    //        (let total_dist[i]=w1+w2+……+wi,then dist[j+1,i]=total_dist[i]-total_dist[j+1])
    //==>min{func(j)}+total_dist[i]+dist2origin[i];
    //        (let func(j)=dp[j]+dist2origin[j+1]-total_dist[j+1])
    //use humdrum queue to optimize time.(finised)
    inline int func(int j){
        return f[j]+dist2origin[j+1]-total_dist[j+1];
    }
    int main(){
        for(scanf("%d",&T);T--;){
            scanf("%d%d",&c,&n);
            dist2origin[0]=total_dist[0]=total_wight[0]=x[0]=y[0]=0;
            for(int i=1,w;i<=n;i++){
                scanf("%d%d%d",&x[i],&y[i],&w);
                dist2origin[i]=ABS(x[i])+ABS(y[i]);
                total_dist[i]=total_dist[i-1]+ABS(x[i]-x[i-1])+ABS(y[i]-y[i-1]);
                total_wight[i]=total_wight[i-1]+w;
            }
            int h=0,t=0;
            for(int i=1;i<=n;i++){
                for(;h<t&&total_wight[i]-total_wight[q[h]]>c;h++);
                f[i]=func(q[h])+total_dist[i]+dist2origin[i];
                for(;h<t&&func(i)<=func(q[t]);t--);
                q[++t]=i;
            }
            printf("%d
    ",f[n]);
            if(T>0) putchar('
    ');
        }
        return 0;
    }

    UVALive - 4794 

    //dp transfer equation:
    //dp(r,c,S)
    //1 dp(r0,c,S0)=dp(r-r0,c,S-S0){1<=r0<r}
    //2 dp(r,c0,S0)=dp(r,c-c0,S-S0){1<=c0<c}
    //3 dp(r,c,S)=dp(c,r,S)
    //use g(r,S) take place of dp(r,c,S){r<=c}, and judge whether is legal or not.
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int N=16,M=105;
    int T,n,cas,x,y,a[N],sum[1<<N];
    bool f[1<<N][M],vis[1<<N][M];
    int bitcount(int x){
        return !x?0:bitcount(x>>1)+(x&1);
    }
    bool dp(int S,int x){
        if(vis[S][x]) return f[S][x];
        vis[S][x]=1;
        bool &ans=f[S][x];
        if(bitcount(S)==1) return ans=1;
        int y=sum[S]/x;
        for(int S0=(S-1)&S;S0;S0=(S0-1)&S){
            int S1=S-S0;
            if(!(sum[S0]%x)&&dp(S0,min(x,sum[S0]/x))&&dp(S1,min(x,sum[S1]/x))) return ans=1;
            if(!(sum[S0]%y)&&dp(S0,min(y,sum[S0]/y))&&dp(S1,min(y,sum[S1]/y))) return ans=1;
        }
        return ans=0;
    }
    int main(){
        while(scanf("%d",&n)==1&&n){
            scanf("%d%d",&x,&y);
            memset(vis,0,sizeof vis);
            memset(f,0,sizeof f);
            for(int i=0;i<n;i++) scanf("%d",&a[i]);
            for(int S=1;S<(1<<n);S++){
                sum[S]=0;
                for(int i=0;i<n;i++){
                    if(S&(1<<i)) sum[S]+=a[i];
                }
            }
            int ALL=(1<<n)-1;bool ans;
            if(sum[ALL]!=x*y||sum[ALL]%x) ans=0;
            else ans=dp(ALL,min(x,y));
            printf("Case %d: %s
    ",++cas,ans?"Yes":"No");
        }
        return 0;
    }
  • 相关阅读:
    远程安装WinXP OEM版系统的痛苦经历
    许可证服务因许可证不够出现占用CPU的故障
    AvayaP133G2和3Com 3300交换机间的Vlan连接
    从win2000升级到win2003后ISA2000缓存的问题
    大型局域网中用ISA隔离部分计算机
    ORACLE学习第二天
    ORACLE ROWID解析
    ORA32773问题解决
    ORACLE学习第三天
    ORACLE表空间迁移
  • 原文地址:https://www.cnblogs.com/shenben/p/6392677.html
Copyright © 2020-2023  润新知