/*
dp[i][j][k] 表示从前i个物品中选j种所花费的金钱数小于等于k的购买方案.
状态转移方程为:
if( k >= p[i] ){
dp[i][j][k] = dp[i][j][k] + dp[i-1][j-1][k-p[i]];
}
dp[i][j][k] = dp[i][j][k] + dp[i-1][j][k];
还有一点要注意的是初始化;
memset( dp, 0, sizeof( dp ) );
for( int i = 0; i <= N; i++ ){
for( int k = 0; k <= M; k++ ){
dp[i][0][k] = 1;
}
}
然后就AC的啦~~~~
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[31][31][501];
int main(){
int T, N, M;
int p[31];
cin >> T;
while( T-- ){
cin >> N >> M;
for( int i = 1; i <= N; i++ ){
cin >> p[i];
}
memset( dp, 0, sizeof( dp ) );
for( int i = 0; i <= N; i++ ){
for( int k = 0; k <= M; k++ ){
dp[i][0][k] = 1;
}
}
for( int i = 1; i <= N; i++ ){
for( int j = 1; j <= i; j++ ){
for( int k = M; k>= 0; k-- ){
if( k >= p[i] ){
dp[i][j][k] = dp[i][j][k] + dp[i-1][j-1][k-p[i]];
}
dp[i][j][k] = dp[i][j][k] + dp[i-1][j][k];
}
}
}
int kinds = -1, sum = -1;
for( int j = N; j >= 1; j-- ){
for( int i = N; i >= j; i-- ){
for( int k = M; k >= 0; k-- ){
if( dp[i][j][k] ){
kinds = j;
sum = dp[i][j][k];
goto HZH;
}
}
}
}
HZH:
if( kinds != -1 ){
printf( "You have %d selection(s) to buy with %d kind(s) of souvenirs.\n", sum, kinds );
}else{
cout << "Sorry, you can't buy anything." << endl;
}
}
return 0;
}
hdu 2126 DP
最新推荐文章于 2019-07-22 09:55:53 发布