uva 674(dp)

来源:互联网 发布:中国联通网络wifi使用 编辑:程序博客网 时间:2024/06/05 19:08

题意:给出一个数字,用无穷多个1,5,10,25,50个美分组成,问用多少种不同的组合方法。

题解:dp经典题,两种做法,记忆化搜索或递推。

第一种记忆化搜索的方法比较难理解,自顶向下,从给出的数字n开始直到状态为0,f[s][i]代表s在5 - i 中面额可用的组成方法数,每次从i开始选择是为了避免重复。

#include <stdio.h>#include <string.h>const int N = 8000;const int coin[5] = {1, 5, 10, 25, 50};long long f[N][5];int n;long long dp(int i, int s) {if (f[s][i] != -1)return f[s][i];f[s][i] = 0;for (int j = i; j < 5 && s >= coin[j]; j++)f[s][i] += dp(j, s - coin[j]);return f[s][i];}int main() {memset(f, -1, sizeof(f));for (int i = 0; i < 5; i++)f[0][i] = 1;while (scanf("%d", &n) != EOF)printf("%lld\n", dp(0, n));return 0;}
递推较好理解,自底向上。
#include <stdio.h>#include <string.h>const int N = 8000;const int coin[5] = {1, 5, 10, 25, 50};long long f[N] = {1};int n;int main() {for (int i = 0; i < 5; i++)for (int j = 0; j < N; j++)f[j + coin[i]] += f[j];while (scanf("%d", &n) != EOF) {printf("%lld\n", f[n]);}return 0;}


0 0