hdu 2126(dp)

点击打开链接


题意:

给你n件物品,m元钱,以及n件物品的价格,求最多物品数的方案数;


刚开始,yf说可以先排序贪心求出最多的件数,然后按照完全背包的思路求解,


#include"stdio.h"
#include"string.h"
#include"algorithm"
using namespace std;
#define N 505

int main()
{
    int T;
    int n,m,t;
    int i,j,k;
    int A[33];
    int dp[N][33];
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
            scanf("%d",&A[i]);

        sort(A+1,A+n+1);

        int ans;
        ans=0;t=0;
        for(i=1;i<=n;i++)
        {
            if(ans+A[i]<=m)
                ans+=A[i],t=i;
            else break;
        }

        if(t==n)
        {
            printf("You have 1 selection(s) to buy with %d kind(s) of souvenirs.\n",n);
            continue;
        }
        if(t==0)
        {
            printf("Sorry, you can't buy anything.\n");
            continue;
        }

        memset(dp,0,sizeof(dp));
        for(i=0;i<=m;i++)dp[i][0]=1;
        for(i=1;i<=n;i++)
        {
            for(j=m;j>=A[i];j--)
            {
                for(k=t;k>=1;k--)
                    dp[j][k]+=dp[j-A[i]][k-1];
            }
        }
        if(dp[m][t]==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",dp[m][t],t);
    }
    return 0;
}


其实 按照直接dp的话也是可以,定义一个dp[505][2],dp[i][0]表示花j元买的最多的物品数,dp[i][1]表示花j元买最多物品的方案数

dp[i][0]=max(dp[i-a][0]+1,dp[i][0])

如果取前者,说明最大件数增加了,则dp[i][1]=dp[i-a][1]

如果取后者,说明最大件数不变,dp[i][1]+=dp[i-a][1];


#include"stdio.h"
#include"string.h"
#define N 505

int main()
{
	int T;
	int n,m;
	int i,j;
	int A[33];
	int dp[N][2];
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++)
			scanf("%d",&A[i]);

		memset(dp,0,sizeof(dp));
		for(i=0;i<=m;i++)dp[i][1]=1;
		for(i=1;i<=n;i++)
		{
			for(j=m;j>=A[i];j--)
			{
				if(dp[j-A[i]][0]+1>dp[j][0])
				{
					dp[j][0]=dp[j-A[i]][0]+1;
					dp[j][1]=dp[j-A[i]][1];
				}
				else if(dp[j-A[i]][0]+1==dp[j][0])
				{
					dp[j][1]+=dp[j-A[i]][1];
				}
			}
		}

		if(dp[m][0]==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",dp[m][1],dp[m][0]);
	}
	return 0;
}


你可能感兴趣的:(背包,HDU,种类数)