链接:点击打开链接
题意:给出面值为1,5,10,25四种钱币分别的数量,求恰好组成面值P的最大钱币数的情况
代码:
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
int x,y,sign;
};
int dp[15][10005];
int main(){
int a,b,c,i,j,k,n,m,sum;
while(scanf("%d%d%d",&n,&sum,&m)!=EOF){
vector<node> s[10005];
memset(dp,-1,sizeof(dp)); //不能初始化成0,否则会导致分组背包
for(i=0;i<n;i++){ //某个组的物品有取不到的可能,但是
scanf("%d%d%d",&a,&b,&c); //这道题数据弱,初始化成0也可以,但
s[a].push_back((node){b,c,0}); //其实是不对的...
}
for(i=1;i<=sum;i++)
dp[0][i]=0;
for(i=1;i<=m;i++)
for(k=0;k<s[i].size();k++)
for(j=sum;j>=s[i][k].x;j--){
if(dp[i][j-s[i][k].x]!=-1) //相当于在当前组内进行01背包
dp[i][j]=max(dp[i][j],dp[i][j-s[i][k].x]+s[i][k].y);
if(dp[i-1][j-s[i][k].x]!=-1) //根据上一层求出当前可以满足的情况
dp[i][j]=max(dp[i][j],dp[i-1][j-s[i][k].x]+s[i][k].y);
}
if(dp[m][sum]==-1)
puts("Impossible");
else
printf("%d\n",dp[m][sum]);
}
return 0;
}