zoukankan      html  css  js  c++  java
  • 旧题复习{6}

    1.树形背包

    洛谷P1273有线电视网==poj1155tele

    //一个孩子一个分组,枚举每个组选几个(给每个孩子分配体积)
    //沙茶的输出打错了
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=3e3+5,INF=1e9;
    int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    int n,m,s,v,w;
    struct edge{
        int v,w,ne;
    }e[N<<1];
    int h[N],cnt=0;
    void ins(int u,int v,int w){
        cnt++;
        e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
        cnt++;
        e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
    }
    
    int d[N][N],son[N];
    void dfs(int u,int fa){
        if(u>=n-m+1) return;
        for(int j=1;j<=m;j++) d[u][j]=-INF;
        
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v,w=e[i].w;
            if(v==fa) continue;
            dfs(v,u);
            son[u]+=son[v];
            for(int j=son[u];j>=1;j--){
                int t=min(j,son[v]);
                for(int k=1;k<=t;k++)
                    d[u][j]=max(d[u][j],d[u][j-k]+d[v][k]-w);
            }
        }
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=n-m;i++){
            s=read();
            while(s--){v=read();w=read();ins(i,v,w);}
        }
        for(int i=n-m+1;i<=n;i++) d[i][1]=read(),son[i]=1;
        dfs(1,0);
        for(int i=m;i>=1;i--) if(d[1][i]>=0) {printf("%d",i);break;}
    }

    2.P2627 修剪草坪

    状态损失最小而不是得到最大,就可以单调队列优化

    最后n-k到n都可以作为答案

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=1e5+5;
    typedef long long ll;
    const ll INF=1e18;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,k,e;
    int q[N],head=1,tail=0;
    ll f[N],sum;
    int main(){
        n=read();k=read();
        q[tail++]=0;
        for(int i=1;i<=n;i++){
            e=read(); sum+=e;
            while(head<=tail&&i-q[head]-1>k) head++;
            f[i]=f[q[head]]+e;
            while(head<=tail&&f[q[tail]]>=f[i]) tail--;
            q[++tail]=i;
        //    printf("f %d %d
    ",i,f[i]);
        }
        ll mn=INF;
        for(int i=n-k;i<=n;i++) mn=min(mn,f[i]);
        printf("%lld",sum-mn);
    }

    3.poj1742coins

    多重背包可行性 F[I][J]前i个凑成j还剩几个i

    注意0是可行的

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=105,M=1e5+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,w[N],c[N];
    int f[M];
    void dp(){
        memset(f,-1,sizeof(f));
        f[0]=0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=m;j++){
                if(f[j]>=0) f[j]=c[i];    
                else f[j]=-1;
            }
            for(int j=0;j<=m-w[i];j++) 
                if(f[j]>0) f[j+w[i]]=max(f[j+w[i]],f[j]-1);
        }
    }
    int main(){
        while(scanf("%d%d",&n,&m)!=EOF&&n+m){
        for(int i=1;i<=n;i++) w[i]=read();
        for(int i=1;i<=n;i++) c[i]=read();
        dp();
        int ans=0;
        for(int j=1;j<=m;j++) if(f[j]>=0) ans++;//,printf("f %d
    ",j);
        printf("%d
    ",ans);
        }
    }

    4.洛谷P2423双塔==vijos

    注意除了-1高度为0也是不可行

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=105,M=2005;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,h[N],sum=0;
    int f[2][M];
    void dp(){
        int now=1;
        memset(f,-1,sizeof(f));
        f[0][0]=0;
        for(int i=1;i<=n;i++,now^=1){
            int pre=now^1;
            for(int j=0;j<=sum;j++){
                f[now][j]=f[pre][j];
                if(j-h[i]>=0&&f[pre][j-h[i]]!=-1) f[now][j]=max(f[now][j],f[pre][j-h[i]]+h[i]);
                if(f[pre][j+h[i]]!=-1) f[now][j]=max(f[now][j],f[pre][j+h[i]]);
                if(h[i]-j>0&&f[pre][h[i]-j]!=-1) f[now][j]=max(f[now][j],f[pre][h[i]-j]+j); 
            }
        }
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++) h[i]=read(),sum+=h[i];
        dp();
        if(f[n&1][0]<=0) puts("Impossible");
        else printf("%d",f[n&1][0]);
    }

    5.LCIS

    注意滚动数组的应用

    mx就应该边推内层边取mx,因为mx取得位置要<j

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=505;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,a[N],b[N];
    int f[N];
    void dp(){
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++){
            int mx=0;
            for(int j=1;j<=m;j++){
                if(a[i]>b[j]) mx=max(mx,f[j]);
                if(a[i]==b[j]) f[j]=mx+1;
            }
        }
    }
    int main(){
        int T=read();
        while(T--){
            n=read(); for(int i=1;i<=n;i++) a[i]=read();
            m=read(); for(int i=1;i<=m;i++) b[i]=read();
            dp();
            int ans=0;
            for(int i=1;i<=m;i++) ans=max(ans,f[i]);
            printf("%d
    ",ans);
        }
    }

    6.poj3636

    二维偏序问题,注意排序时相等怎么办

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2e4+5,INF=1e9;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n;
    struct doll{
        int w,h;
        bool operator <(const doll &r)const{
            if(w==r.w) return h>r.h;
            return w<r.w;
        }
    }d[N];
    int f[N],g[N],a[N];
    inline bool cmp(int a,int b){return a>b;}
    int dp(){
        int ans=0;
        for(int i=1;i<=n;i++) g[i]=-INF,a[i]=d[i].h;
        for(int i=1;i<=n;i++){
            int k=upper_bound(g+1,g+1+n,a[i],cmp)-g;
            f[i]=k;
            g[k]=a[i];
            ans=max(ans,f[i]);
            //printf("f %d %d
    ",i,f[i]);
        }
        return ans;
    }
    int main(){
        int T=read();
        while(T--){
            n=read();
            for(int i=1;i<=n;i++) d[i].w=read(),d[i].h=read();
            sort(d+1,d+1+n);
            printf("%d
    ",dp());
        }
    }
  • 相关阅读:
    override 和 重载的区别? Kevin
    EntityFramework SaveChange()方法不能更新的问题 Kevin
    Visual Studio 2010中找不到 entity framework模版 Kevin
    在数据库发生更改时更新 .edmx 文件(MSDN) Kevin
    MVC 3 RoutingSystem Kevin
    用递归的方法计算第30位斐波那契数列的值 Kevin
    log4net的日志输出格式log4net.Layout.PatternLayout用法 Kevin
    JavaScript: The Definitive Guide, 6th Edition Chapter 1 Note 1 Kevin
    闲谈生意人、商人和企业家的区别
    stlport 5.10 编译 更加容易了(visual studio 2005)
  • 原文地址:https://www.cnblogs.com/candy99/p/6071833.html
Copyright © 2011-2022 走看看