挑战多重部分和问题

poj1742可套用此模板

题意:有n种不同的数字a[i],每种各b[i]个,判断这些数字可以组成多少个不大于m的数,组成的这些数分别是多少,

                   判断是否可以组成m。

题解dp[i+1][j]:用前i种数加和得到j时第i种数剩余多少个(不能加和得到i的情况下为-1)

如果前i种数相加能得到 j 的话,第i个数可以留下b[i]个,

如果前i种数相加得到j-a[i]时第i种数还剩下k(k>0)个,用i种数相加得到j时,第i种数还剩余k-1个

      b[i](dp[i][j]>=0)

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

      dp[i+1][j-a[i]]-1

#include<cstdio>  
#include<cstring>  
#include<iostream>
using namespace std;
int n,m;
int a[100],b[100];
int dp[100];

void solve()
{
    memset(dp,-1,sizeof(dp));
    dp[0]=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=m;j++)
        {
            if(dp[j]>=0)//前i种数已经组成j 
                dp[j]=b[i];
            else if(j<a[i]||dp[j-a[i]]<=0)//加a[i]就越界,或者b[i]<0 
                dp[j]=-1;
            else
                dp[j]=dp[j-a[i]]-1;//前i个数组成j-a[i],用一个a[i]组成j 
        }
    }
    int ans=0;
    for(int i=1;i<=m;i++)
    {
        if(dp[i]>=0)
        {
            ans++;
            cout<<i<<" ";//可以组成的数分别时什么 
        }    
    }
    cout<<endl;
    cout<<ans<<endl;//可以组成多少个数 
    //判断是否可以组成m 
//    if(dp[m]>=0)
//        cout<<"yes"<<endl;
//    else
//        cout<<"no"<<endl;
}
int main()
{
    while(cin>>n>>m)
    {
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        for(int i=0;i<n;i++)
        {
            cin>>b[i];
        }
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/renwjing/p/7561318.html