题目:给你硬币种类,判断要达到某一值,有多少种组成方式?
解法:DP,d[i][j] 表示用了前i种硬币,组合j的方式。
转移方程: d[i+1][j] = max{ d[i][j], d[i][j-coins[i+1]] }。
实际编程可以使用滚动数组,减少空间复杂度; 并避免用分数; 另外还可以考虑让所用硬币值除以5;
/*
注意要用long long
*/
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <iomanip>
using namespace std;
const int MAXN = 30005;
int coins[] = {5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000};
int type = sizeof(coins) / sizeof(coins[0]);
long long d[MAXN];
void dp()
{
d[0] = 1;
for(int i=0; i<type; i++) {
for(int j=5; j<=30000; j+=5) if(j >= coins[i]){
d[j] += d[j-coins[i]];
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
dp();
double r;
while(scanf("%lf", &r)==1 && r>1e-9) {
cout << fixed << setw(6) << setprecision(2) << r
<< setw(17) << d[(int)((r+1e-9)*100)] << endl;
}
}