zoukankan      html  css  js  c++  java
  • 多重部分和问题

    有n种不同大小的数字ai,每种各mi个。判断是否可以从这些数字之中选出若干使它们的和恰好为K。

    限制条件 1<=n<=100,1<=ai,mi<=100000,1<=K<=100000.

    dp[i+1][j]:用前i种数字能否加和成K

    为了前i种数字能加和成K,需要能用前i-1种数字加和成j,j-a...j-mi*ai中的某一种

    因此dp[i+1][j]=(0<=k<=mi且k*ai<=j时存在使得dp[i][j-k*ai]为真的k)

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<memory.h>
     4 #define INF 10000000
     5 using namespace std;
     6 const int max_n=101;
     7 int a[max_n+1];
     8 int m[max_n+1];
     9 int n,r,K;
    10 int main()
    11 {
    12     cin>>n;
    13     for(int i=0;i<n;i++)
    14     {
    15         cin>>a[i]>>m[i];
    16     }
    17     cin>>K;
    18     bool dp[n+1][K+1];
    19     fill(dp[0],dp[0]+K+1,false);
    20     dp[0][0]=true;
    21     for(int i=0;i<n;i++)
    22     {
    23         for(int j=0;j<=K;j++)
    24         {
    25             for(int k=0;k*a[i]<=j&&k<=m[i];k++)
    26             {
    27                 dp[i+1][j]|=dp[i][j-k*a[i]];
    28             }
    29         }
    30     }
    31     cout<<dp[n][K]<<endl;
    32     return 0;
    33 }
    View Code

    优化如下

    dp[i+1][j]:用前i种数加和得到j时第i种数最多能剩余多少个

    dp[i+1][j]=mi  (dp[i][j]>=0)

          -1  (j<ai||dp[i+1][j-ai]<=0)

          dp[i+1][j-ai]-1  (其他)

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<memory.h>
     4 #define INF 10000000
     5 using namespace std;
     6 const int max_n=101;
     7 int a[max_n+1];
     8 int m[max_n+1];
     9 int n,r,K;
    10 int main()
    11 {
    12     cin>>n;
    13     for(int i=0;i<n;i++)
    14     {
    15         cin>>a[i]>>m[i];
    16     }
    17     cin>>K;
    18     int dp[K+1];
    19     memset(dp,-1,sizeof(dp));
    20     dp[0]=0;
    21     for(int i=0;i<n;i++)
    22     {
    23         for(int j=0;j<=K;j++)
    24         {
    25             if(dp[j]>=0)
    26             {
    27                 dp[j]=m[i];
    28             }
    29             else if(j<a[i]||dp[j-a[i]]<=0)
    30             {
    31                 dp[j]=-1;
    32             }
    33             else
    34             {
    35                 dp[j]=dp[j-a[i]]-1;
    36             }
    37         }
    38     }
    39     cout<<dp[K]<<endl;
    40     return 0;
    41 }
    View Code
  • 相关阅读:
    urllib使用四--urlencode,urlparse,
    urllib使用三--urlretrieve下载文件
    urllib使用二
    urllib使用一
    python使用网易邮箱发邮件
    python QQ邮件发送邮件
    可以字符串string转化成list,tuple,dict的eval()方法
    一行代码将两个列表拼接出第三个列表(两个可迭代对象相加产生第三个可迭代对象)--map()方法
    把列表中的元素拼接成字符串
    Runtime 类
  • 原文地址:https://www.cnblogs.com/wangkaipeng/p/6430144.html
Copyright © 2011-2022 走看看