1. 程式人生 > >poj 1742 Coins 【多重揹包可重性】

poj 1742 Coins 【多重揹包可重性】

題意:有n種不同大小的數字ai,每種各mi個,判斷是否可以從這些數字之中選出若干使他們的和恰好為k。

輸入:

n=3

a={3,5,8}

m={3,2,2}

k=17

輸出: YES(3*3+8)

程式碼實現:(白書62頁就是,裡面有詳細的介紹,因為我本人那個排版的問題,暫時就先這樣)

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;
int dp[100][maxn],a[maxn],c[maxn];
//dp[i+1][j]:=用前i種數加和得到j時第i種數最多能剩餘多少個(不能加和得到i的情況下為-1)
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(int i=0;i<n;i++)
        scanf("%d",&c[i]);
    int k;
    scanf("%d",&k);
    memset(dp,-1,sizeof dp);
    dp[0][0] = 0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=k;j++)
        {
            if(dp[i][j] >= 0)
                dp[i+1][j] = c[i];
            else if(j<a[i] || dp[i+1][j-a[i]]<=0)
                dp[i+1][j] = -1;
            else
                dp[i+1][j] = dp[i+1][j-a[i]]-1;
        }
    }
    if(dp[n][k] >= 0)
        printf("YES\n");
    else
        printf("NO\n");
    return 0;
}

題意:與最上面的題意類似,就是恰好等於k改成小於等於k,求滿足題意的數目(還不是太理解,寫下來慢慢理解)降維

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ms(a) memset(a,0,sizeof a)
const int maxn = 1e5+10;
int a[maxn],c[maxn],dp[maxn];
int main()
{
    int n,m;
    while(~scanf("%d %d",&n,&m)&&n+m)
    {
        ms(a);
        ms(c);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
            scanf("%d",&c[i]);
        memset(dp,-1,sizeof dp);
        dp[0] = 0;
        for(int i=1;i<=n;i++)
        {
            dp[0] = c[i];
            for(int j=1;j<=m;j++)
            {
                if(dp[j] >= 0)
                    dp[j] = c[i];
                else if(j<a[i] || dp[j-a[i]]<=0)
                    dp[j] = -1;
                else if(dp[j-a[i]]>=0)
                    dp[j] = dp[j-a[i]] - 1;
            }
        }
        int cnt = 0;
        for(int i=1;i<=m;i++)
        {
            if(dp[i] >= 0)
                cnt++;
        }
        printf("%d\n",cnt);
    }
    return 0;
}