题意:我有m元,有n个纪念品,已知它们分别的价格,输出我最多能买多少个不同的纪念品,以及能买到最多不同纪念品时我可选择的方案数。
思路:将m作为容量,纪念品的价格作为消耗,每个纪念品的价值为1(件),容易求得我最多能买的纪念品数。用一个数组s记录方案数,数组kind记录不同纪念品数。
#include
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif
int t, n, mon, price[35], kind[505], s[505], m;
scanf("%d" ,&t);
while(t--)
{
scanf("\n");
scanf("%d%d", &n, &mon);
for(int i = 1; i <= n; i++)
scanf("%d", &price[i]);
for(int i = 0; i <= mon; i++)
{
kind[i] = 0; s[i] = 1;
}
for(int i = 1; i <= n; i++ )
{
for(int j = mon; j >= price[i]; j--)
{
if(kind[j - price[i]] + 1 >= kind[j])
{//对于i-th纪念品找到不同纪念品数大于或等于前i-1th的情况
if(kind[j - price[i]] + 1 == kind[j])
{//不同纪念品数不增加则方案数在原来基础上加
s[j] += s[j - price[i]];//这里要注意不是简单的+1
}
else
{//不同纪念品数增加
s[j] = s[j - price[i]];
kind[j] = kind[j - price[i]] + 1;
}
//printf("s[%d]=%d\n", j, s[j]);
}
}
}
if(kind[mon] == 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", s[mon], kind[mon]);
}
}
return 0;
}