Hangdian 2844 (backpack + system processing).

Click to open the link

Title meaning:

Ask you to give the M range (1~M), respectively, use the given coins and the corresponding amount. Find out how much money can be collected between (1~M), including the boundary. .

As soon as you look at this question, you should be able to guess that it is done with DP, and you can also think of using generating functions. But looking at the data again, we can rule out the general DP, and the M value of the generating function is too large, and it may time out, so this is also not feasible.

So let's see if DP can be done! ! However, the data may be too large for direct DP, so it must be considered separately. —: When the product of a set of data is greater than M, and when it is less than, consider separately here.

When the data product is greater than, you can use a complete backpack (which can be used indefinitely) until the conditions are not met. Two: When it is less than, whether the current value is added or not, it may produce different results. Therefore, you can use the 01 backpack (plus or not) to solve the problem.

Then look at the code: (Look at the code carefully)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using  namespace std;
const int maxn=100005;
int a[105],c[105];
int dp[maxn];
int n,m;
void compty(int x)//完全背包。
{
    int i;
    for(i=x;i<=m;i++)
        dp[i]=max(dp[i],dp[i-x]);
}
void beibao_01(int x)//01背包。可以看着次数。
{
    int i;
   for(i=m;i>=x;i--)
   {
       dp[i]=max(dp[i],dp[i-x]);
   }
}
void shuju(int cons,int n)
{
    int k;
    if(cons*n>m)//当输入的数据大于总的M时,应该考虑可以加入的次数,就是(转换妫完全背包题),完全背包,可以去好多次,直到不满足条件为止!
    compty(cons);
    else
    {
        k=1;
        while(k<n)//当然在小于时就必须考虑这依次是否家还是不加,这就考虑的是01背包的问题。
        {
            beibao_01(cons*k);
            n-=k;
            k++;
        }
        beibao_01(cons*n);
    }
}
int main()
{
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)break;
        memset(a,0,sizeof(a));
        memset(c,0,sizeof(c));
        for(i=1;i<=n;i++)scanf("%d",&a[i]);
        for(i=1;i<=n;i++)scanf("%d",&c[i]);
        memset(dp,0,sizeof(dp));//初始化,
        dp[0]=1;
        for(i=1;i<=n;i++)
        {
           shuju(a[i],c[i]);//依次考虑,分别对你每一个数据谈论!!
        }
        int sum=0;
         for(i=1;i<=m;i++)
         {
             if(dp[i])
             sum++;

         }
        cout<<sum<<endl;
    }
    return 0;
}


 

Guess you like

Origin blog.csdn.net/u010200793/article/details/16845019