链接: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;
}