zoukankan      html  css  js  c++  java
  • poj 01背包

    首先我是按这篇文章来确定题目的。

    poj3624 Charm Bracelet

    模板题

    没有要求填满,所以初始化为0就行

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int w[3403];
    int h[3403];
    int n,m;
    int dp[12880+9];
    int main()
    {
       // freopen("input.txt","r",stdin);
      scanf("%d%d",&n,&m);
      for(int i=0;i<n;i++)
        scanf("%d%d",&w[i],&h[i]);
      for(int i=0;i<n;i++)
        for(int j=m;j>=w[i];j--)
         dp[j]=max(dp[j],dp[j-w[i]]+h[i]);
      printf("%d
    ",dp[m]);
    }

    poj3628 Bookshelf 2

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int h[25];
    int dp[21000000];
    int n,s;
    int sum;
    int main()
    {
        // freopen("input.txt","r",stdin);
        scanf("%d%d",&n,&s);
        for(int i=0;i<n;i++){
            scanf("%d",&h[i]);
            sum+=h[i];
        }
        int ans=0;
        for(int i=0;i<n;i++)
            for(int j=sum;j>=h[i];j--)
            dp[j]=max(dp[j],dp[j-h[i]]+h[i]);
            for(int i=0;i<=sum;i++)
                if(dp[i]>=s){
                ans=dp[i]-s;
                break;
                }
            printf("%d
    ",ans);
    }
    poj3211 Washing Clothes
    这道题就是两个人同时在一个盆子里洗衣服,算的时候每件衣服独立算,然后相同衣服之间可以连续,我们需要求得是在一半体积下那个花的时间大的值。
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<iostream>
    #include<vector>
    #include<cstring>
    #include<map>
    using namespace std;
    int n,m;
    map<string,int> q;
    int w[105];
    vector<int> g[11];
    int dp[50000];
    int main()
    {
         // freopen("input.txt","r",stdin);
         while(scanf("%d%d",&n,&m)==2&&n&&m)
         {
               string str;
               memset(w,0,sizeof(w));
               q.clear();
               for(int i=0;i<=10;i++)
                g[i].clear();
             for(int i=0;i<n;i++)
             {
                 cin>>str;
                 q[str]=i;
             }
             for(int i=0;i<m;i++)
             {
                int t,v;
                cin>>v>>str;
                t=q[str];
                g[t].push_back(v);
                w[t]+=v;
             }
             int ans=0;
             for(int i=0;i<n;i++)
             {
               int v=w[i]/2;
               memset(dp,0,sizeof(dp));
               for(int j=0;j<g[i].size();j++)
                 for(int k=v;k>=g[i][j];k--)
                 {
                     dp[k]=max(dp[k],dp[k-g[i][j]]+g[i][j]);
                 }
                 ans+=(w[i]-dp[v]);
             }
             printf("%d
    ",ans);
         }
    }

    poj1745 Divisibility

    这道题如果取摸后范围比较小,第二维不大于100,然后记忆化背包(非递归搜索),根据能达到的值推能达到的值,衍生出前n个时的所有状态。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<iostream>
    #include<vector>
    #include<cstring>
    #include<map>
    using namespace std;
    int n,k;
    int c[10005];
    int dp[10005][105];
    int main()
    {
        //freopen("input.txt","r",stdin);
        int t;
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&t);
            if(t<0) t=-t;
            t%=k;
            c[i]=t;
        }
        dp[0][c[0]]=1;
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<k;j++)
            {
                if(dp[i-1][j])
                {
                    dp[i][(j+c[i])%k]=1;
                    dp[i][(j+k-c[i])%k]=1;
                }
            }
        }
        if(dp[n-1][0])
            printf("Divisible
    ");
        else
            printf("Not divisible
    ");
    }

    poj1976  A Mini Locomotive

    3辆车运货,共有n堆货,每辆可以运连续k堆,求最大运货量

    保证k*3<=n;也就是说要运货量最大必须堆数为k。

    dp[i][j]为前j次前i堆最大运货量的最大运货量

    如果i<j*k;那么只能全运

    第i堆不运:dp[i-1][j]

    第i堆运:dp[i-k][j-1]+sum;

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int a[50005];
    int n,k;
    int dp[50005][4];
    int main()
    {
         //freopen("input.txt","r",stdin);
         int cas;
         scanf("%d",&cas);
         while(cas--)
         {
             scanf("%d",&n);
             a[0]=0;
          for(int i=1;i<=n;i++){
             scanf("%d",&a[i]);
             a[i]+=a[i-1];
            }
             scanf("%d",&k);
             memset(dp,0,sizeof(dp));
             for(int i=1;i<=n;i++)
             {
                 for(int j=1;j<=3;j++)
                 {
                     if(i<j*k)
                        dp[i][j]=i;
                     else
                     dp[i][j]=max(dp[i-1][j],dp[i-k][j-1]+a[i]-a[i-k]);
                 }
             }
             printf("%d
    ",dp[n][3]);
         }
    }

    poj1837 Balance

    状态压缩求方案数

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int k,n,f;
    int dp[21][15100];
    int h[21];
    int w[21];
    int main()
    {
       //  freopen("input.txt","r",stdin);
        scanf("%d%d",&f,&n);
        for(int i=0;i<f;i++)
            scanf("%d",&h[i]);
        for(int i=1;i<=n;i++)
            scanf("%d",&w[i]);
        dp[0][7500]=1;
        for(int i=1;i<=n;i++)
        {
           for(int k=0;k<=15000;k++)
            {
                if(dp[i-1][k])
                {
                    for(int j=0;j<f;j++)
                    {
                        dp[i][k+h[j]*w[i]]+=dp[i-1][k];
                    }
                }
            }
        }
        printf("%d
    ",dp[n][7500]);
    }

    poj1948  Triangular Pastures

    n个线,组一个三角形,求三角形的最大面积。

    海伦公式

    • formula,p为半周长

    因为周长已知,知道两条边就能确定面积。

    设dp[i][j](i>j),然后确定每一条边是否加入那个边,由已知状态推出未知状态,随之更新最大面积。

    每条边不可能超过周长的一半。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int n;
    int a[45];
    int c;
    int dp[1605][1605];
    int aa[4];
    // a+b>c-a-b
    //
    int check(int x,int y)
    {
     aa[0]=x;
     aa[1]=y;
     aa[2]=c-x-y;
      if(aa[0]+aa[1]<aa[2]||aa[1]+aa[2]<aa[0]||aa[0]+aa[2]<aa[1])
        return -1.0;
        double t=c*1.0/2;
        double ans=sqrt(t*(t-aa[0])*(t-aa[1])*(t-aa[2]))*100.0;
        return ans;
    //   printf("%d %d %d %d
    ",aa[0],aa[1],aa[2],(int)ans);
    }
    
    int main()
    {
        // freopen("input.txt","r",stdin);
         //printf("")
        scanf("%d",&n);
        for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        c+=a[i];
        }
        dp[0][0]=1;
        int ans=-1.0;
        for(int i=0;i<n;i++)
        {
            for(int j=c/2;j>=0;j--)
            {
                for(int k=c/2;k>=j;k--)
                {
                        if(j>=a[i]&&dp[j-a[i]][k])
                            dp[j][k]=1;
                        if(k>=a[i]&&dp[j][k-a[i]])
                            dp[j][k]=1;
                        if(dp[j][k])
                            ans=max(ans,check(j,k));
                        //   printf("%d
    ",ans);
                }
            }
        }
        printf("%d
    ",ans);
    }

    poj2923

    待定

  • 相关阅读:
    高性能网站优化——兼容
    高性能网站优化——开发
    leetcode刷题日记: 19.删除链表的倒数第k个节点
    大数据处理技术学习
    <java复习>返回可变对象引用的get方法要点
    <C++网络编程随笔>常用Socket函数总结
    <leetcode每日一题>数组中的第K个最大元素
    <leetcode每日一题>二叉树的LCA查找
    codeforce round615 div3 B
    暑假作业竟然如此芳香(hdu4145枚举+贪心)
  • 原文地址:https://www.cnblogs.com/acliang/p/4957550.html
Copyright © 2011-2022 走看看