码迷,mamicode.com
首页 > 其他好文 > 详细

hdu acm 2844 Coins 解题报告

时间:2014-08-03 15:06:15      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   io   for   

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2844

题目意思:有A1,A2,...,An 这 n 种面值的钱,分别对应的数量是C1,C2,...,Cn。问根据这么多数量的钱 能组成多少个 <= m 的钱。

      如果用多重背包来做,超时了...如果用记忆化搜索,还是...超时= =.....

      这个方法是网上搜的,觉得好神奇,能看懂一些。

      它是根据完全背包的思路做的,但是需要限制每种币种的使用数量,于是就多了个used[] 数组来记录了。 ! f[j]表示之前没有组成 j 这么多的钱,f[j] = 1 就表示已经组成过 j 那么多的钱了,下次再遇到同样能构成 j 那么多的钱就不要再重复算了。 这个f[j-A[i]] 有一点点让我难以理解,应该就是 如果在不超过C[i] 数量(used[j-A[i]])的情况下,用一定数量的 A[i] 再加上之前用过的 A[i-1] ,A[i-2],...,A[1] (当然也可以不用,也可以用部分) 这些币值能能够组成 j 这么多钱。

      还有这句:used[j] = used[j-A[i]] + 1;  也有一点不太懂,不知道为什么要从used[j-A[i]] 前提下 +1......  

     代码中注释部分可能有误导别人的成分,欢迎指出不足(哎~~~没办法啦,网上的这份代码,好像没有人写过注释,我也是按自己理解啦= =)

      

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int maxn = 1e5 + 5;
 7 const int N = 100 + 5;
 8 
 9 int A[N], C[N];
10 int f[maxn], used[maxn];
11 
12 int main()
13 {
14     int n, m;
15     while (scanf("%d%d", &n, &m) != EOF && (m+n))
16     {
17         memset(f, 0, sizeof(f));
18         for (int i = 0; i < n; i++)
19             scanf("%d", &A[i]);
20         for (int i = 0; i < n; i++)
21             scanf("%d", &C[i]);
22         f[0] = 1;
23         int ans = 0;
24         for (int i = 0; i < n; i++)
25         {
26             for (int j = 0; j <= m; j++)
27                 used[j] = 0;    // used[j]表示当前这种面值为j时用了A[i]多少次,它的使用时限制A[i]被使用的数量,否则就可以用无限个了
28             for (int j = A[i]; j <= m; j++)
29             {
30                 if (!f[j] && f[j-A[i]] && used[j-A[i]] < C[i])  // 用f[j]表示能组成这价值为j的钱和不能(0与1), f[j-A[i]] 表示之前能组成j-A[i]这么多钱
31                 {
32                 // printf("!f[j]: !f[%d];  f[j-A[i]]: f[%d]\n", j, j-A[i]);
33                 //    printf("used[j-A[i]]: used[%d] = %d, C[i]: C[%d] = %d\n", j-A[i], used[j-A[i]], i, C[i]);
34                     f[j] = 1;
35                     used[j] = used[j-A[i]] + 1;  // 组成j这么多钱还需要用多一次A[i]这样的币值
36                     ans++;
37                 //    printf("used[%d] = %d\n", j, used[j]);
38                 //    printf("组成面值为 %d 时用了 A[%d](即 %d) %d 次\n\n", j, i, A[i], used[j]);
39                 }
40             }
41         }
42         printf("%d\n", ans);
43     }
44     return 0;
45 }

 

    输出变量图,真诚奉献,真心强大啊~~~

    bubuko.com,布布扣

   

hdu acm 2844 Coins 解题报告,布布扣,bubuko.com

hdu acm 2844 Coins 解题报告

标签:style   blog   http   color   使用   os   io   for   

原文地址:http://www.cnblogs.com/windysai/p/3888329.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!