1、这是一个完全背包问题,按照《背包九讲》里的来就好,注意最后答案可能为long long型。
/*
ID:mrxy564
PROG:money
LANG:C++
*/
#include<cstdio>
#include<cstring>
using namespace std;
long long a[30],dp[10010];
int v,n;
void CompletePack(int cost,int weight){
for(int j=cost;j<=n;j++)
dp[j]+=dp[j-cost];
}
int main(){
freopen("money.in","r",stdin);
freopen("money.out","w",stdout);
scanf("%d%d",&v,&n);
for(int i=0;i<v;i++){
scanf("%d",&a[i]);
}
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=0;i<v;i++)
CompletePack(a[i],1);
printf("%lld\n",dp[n]);
return 0;
}
官方题解:
We use dynamic programming to count the number of ways to make n cents with the given coins. If we denote the value of the kth coin by c_k, then the recurrence is:
nway(n, k) = no. of ways to make n cents with the first k types of coins nway(n, k) = nway(n, k-1) + nway(n-c_k, k)
This just says the number of ways to make n cents with the first k coins is the number of ways to make n cents using the first k-1 coins (i.e., without using the kth coin) plus the number of ways to make n-c_k cents using the first k coins. For the second set of ways, we then add the kth coin to arrive at a total of n cents.
We keep track of the number of ways to total "n" cents in "nway", updating the array as we read the value of each coin.
/* PROG: money ID: rsc001 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define MAXTOTAL 10000 long long nway[MAXTOTAL+1]; void main(void) { FILE *fin, *fout; int i, j, n, v, c; fin = fopen("money.in", "r"); fout = fopen("money.out", "w"); assert(fin != NULL && fout != NULL); fscanf(fin, "%d %d", &v, &n); nway[0] = 1; for(i=0; i<v; i++) { fscanf(fin, "%d", &c); for(j=c; j<=n; j++) nway[j] += nway[j-c]; } fprintf(fout, "%lld\n", nway[n]); }