HDU2082 找单词(背包)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2082

题意:

告诉你每个单词的个数!

然后价值:A是1.B是2……Z是26

求出单词相互组合后,总价值少于50的单词有几个

背包

#include<iostream>  
#include<cstring>  
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
using namespace std;

int a[30];
int dp[30][51];
int main()
{
//	freopen("D://input.txt", "r", stdin);
//	freopen("D://output.txt", "w", stdout);
	int T;
	scanf("%d", &T);
	while (T--)
	{
		memset(dp, 0, sizeof(dp));
		int i, j, k;
		for (i = 1; i <= 26; i++)
			scanf("%d", &a[i]);
		for (i = 0; i <= 26; i++)
			dp[i][0] = 1;
		/*
		第一维表示,当前加入了i个字母以后所能得到的答案,然后dp的时候一个一个加入新的字母,递推求价值
		*/
		for (i = 1; i <= 26; i++)//枚举每个单词
		{
			for (j = 0; j <= 50; j++)//枚举价值
			{
				dp[i][j] = dp[i - 1][j];//先加上去掉当前字母的价值
				for (k = 1; k <= a[i]; k++)//枚举当前字母个数
				{
					if (j >= k*i)//k*i是k个当前字母所能产生的价值,然后dp[i][j]就要加上dp[i - 1][j - k*i]所贡献的价值
						dp[i][j] += dp[i - 1][j - k*i];//dp[i - 1][j - k*i]表示枚举到i-1个字母的时候,产生j - k*i价值时的答案,加上即可
					else break;
				}
			}
		}
		int ans = 0;
		for (i = 1; i <= 50; i++)
			ans += dp[26][i];//加上从1到50个价值的所有可能,所以第一维是26,每一个字母都要考虑进去
		printf("%d\n", ans);
	}
//	printf(".6lf\n",(double)clock()/CLOCKS_PER_SEC);
	return 0;
}


你可能感兴趣的:(HDU2082 找单词(背包))