hdu2126——Buy the souvenirs——————【01背包记录物品最多时种数】

来源:互联网 发布:网络车管所 编辑:程序博客网 时间:2024/04/19 01:04

/**

   解题思路:多加一维表示物品个数。dp[j][k]代表背包容量为j,物品个数为k时的组合种类数目。

*/

/*

   题目大意:给你n种物品,有m块钱,然后给出n种物品的花费,问物品个数最多时的组合种数有多少。

*/

#include<stdio.h>#include<iostream>#include<string.h>using namespace std;#define maxn 550int dp[maxn][35],n,m,t,flag;int c[35];int main(){    int i,j,k;    scanf("%d",&t);    while(t--)    {        memset(c,0,sizeof(c));        memset(dp,0,sizeof(dp));        scanf("%d %d",&n,&m);        flag=-1;        int Min=0x3f3f3f3f;        for(i=0; i<n; i++){            scanf("%d",&c[i]);            if(Min>c[i])                Min=c[i];        }        if(Min>m){            printf("Sorry, you can't buy anything.\n");continue;        }        dp[0][0]=1;         //起点        for(i=0; i<n; i++)        {            for(j=m; j>=c[i]; j--)    //花j元            {                for(k=n; k>=1; k--)   //买k种                {                    if(dp[j-c[i]][k-1])                    {                        dp[j][k]+=dp[j-c[i]][k-1];                        if(dp[j][k]!=0&&k>flag)                            flag=k;   //计最大种数                    }                }            }        }        int ans=0;  //计组合数        for(i=1; i<=m; i++)        {            if(dp[i][flag]!=0)                ans+=dp[i][flag];        }        if(ans==0)            printf("Sorry, you can't buy anything.\n");        else            printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.\n",ans,flag);    }    return 0;}


0 0