###### Hdu 2162 Buy the souvenirs(一个求最优解总数的01背包题)

				if(dp[j - v[i]]+1>dp[j]){
dp[j] = dp[j - v[i]] + 1;
G[j] =  G[j - v[i]];
}
else if(dp[j - v[i]]+1==dp[j]){
G[j] += G[j - v[i]];
}

(1)更新G[i][j] = G[i-1][j-v[i]];

(2)增加G[i][j] = G[i-1][j] + G[i-1][j-v[i]];

(3)不变G[i][j] = G[i-1][j];

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cmath>

using namespace std;
const int INF = 0x7fffffff;

int dp[505];
int G[505];
int v[35];
int main()
{
//freopen("/home/user/桌面/in","r",stdin);
int ca;
scanf("%d",&ca);
while(ca--){
memset(dp,0,sizeof(dp));
memset(G,0,sizeof(G));
dp[0] = 0;

int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&v[i]);

G[0]=1;
for(int i=1;i<=n;++i){
for(int j=m;j>=v[i];--j){
if(dp[j - v[i]]+1>dp[j]){
dp[j] = dp[j - v[i]] + 1;
G[j] =  G[j - v[i]];
}
else if(dp[j - v[i]]+1==dp[j]){
G[j] += G[j - v[i]];
}
}
}
//		for(int i=0;i<=m;++i){
//			cout<<"  G["<<i<<"]:"<<G[i]<<"  dp["<<i<<"]:"<<dp[i]<<endl;
//		}
int mk=dp[m],se=0;
for(int i=0;i<=m;++i){
if(dp[i] == mk){
se += G[i];
}
}
if(dp[m] > 0)printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.\n",se,dp[m]);
else printf("Sorry, you can't buy anything.\n");
}
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}

#### 背包问题——“01背包”最优方案总数的求解

2015-02-04 19:59:39

2015-08-10 08:28:15

#### 背包问题——“01背包”最优方案总数分析及实现

2011-11-28 13:25:11

#### 校招编程题：求最优解题方案

2017-12-07 21:44:00

#### 背包问题小总结 习题（动态规划01背包（第k优解）完全背包，多重背包）acm杭电HDU2639，HDU2602，HDU1114，HDU2191

2017-04-15 16:46:45

#### HDU_01背包系列

2016-07-22 12:22:29

#### 背包问题----完全背包(最优方案总数分析及实现)

2014-07-17 14:31:00

#### Codeforces 765F. Souvenirs

2017-02-16 08:09:15

2016-02-08 23:24:31

#### Codeforces Round #397 F. Souvenirs(线段树,离线)

2017-02-23 15:58:05