uva357

来源:互联网 发布:mysql锁表 解锁 编辑:程序博客网 时间:2024/06/08 14:37

题目的意思就是有1,5.10.25.50面值的硬币..

组成目标值的方法有多少种..

首先我们可以想到,用这些硬币组成11有多少种.

就是组成10的种数,加上组成6的种数,加上组成1的种数,因为这些面值都是加上一枚硬币就得到11了.

然后我们又能继续去求1组成10的种数,那么明显就是9,5,0的组成数的和.

依次递归.并且每次都用d 数组记录下来,防止重复计算.

而d数组是二维的,第二维是用来防止多算,比如拿了1再拿5,和拿了5再拿1只能算一种.,所以我们算的时候,必须从小到大取,你不能去 1 ,5 , 1 ,只能取 1 ,1 ,5 .接下去算的那一个只能大于等于前一个 ,所以d[ 11 ][ 0 ],后面那个小标代表用到哪一个了..如果是d[ 9][ 1] ,就代表,还差9分钱,而你能取得硬币只有5.10.25.50这四种面值了..


30000的话最后值很大,要用long long;

AC代码:


#include<stdio.h>#include<string.h>#define ll long long const int MAXN = 30005;ll d[MAXN][5];int coin[5] = {1,5,10,25,50};ll dp(ll s ,ll i) {if (d[s][i] != -1)return d[s][i];d[s][i] = 0;for (int j = i  ; j < 5 && coin[j] <= s ;j++) {d[s][i] += dp(s - coin[j] , j);}return d[s][i];}int main () {memset(d, -1 ,sizeof(d));for (int i = 0 ; i < 5 ;i++) {d[0][i] = 1;}ll tar;while(~scanf("%lld",&tar)) {ll res;res= dp(tar , 0);if (res == 1)printf("There is only 1 way to produce %lld cents change.\n",tar);elseprintf("There are %lld ways to produce %lld cents change.\n",res,tar);}}


0 0