hdoj2844

呵呵哒……简直要被这道题玩死了好吗(掀桌

zb大大说很容易……我还不信……我还日思夜想日思夜想……了好久……

呵呵

呵呵

幸亏问了问lcl学长……不然……朕就要被它玩死……不过……我是有受虐倾向吗……为什么我还觉得这个过程很好玩……算了……算法的魅力好了

——————————————

一开始的思路,先转化成01背包,然后类似之前做过的找零钱问题(完全被爆>_<),因为是之前先转成01所以逆序。

if (dp[j]) dp[j+w[i]]++;  差不多是介个意思……

哼,我都懒的看自己那破代码了

提交超时,妥妥的超时,哼

然后搜了一下题解,发现可以直接用多重背包的模板,直接用多重背包过程中得到的所有值标记一下再统计一下妥妥的AC,哼,没爱了>_<妈蛋

——————————————

不废话了,直接上代码//真的好伤心,这一句吐槽真的憋了好久了『真是不努力就不知道智商的重要性!!!摔>_<』可是还是要憋回去,因为像我这样牛的人怎么可能认怂呢,啊摔!

——————————————

突然想回去看火影了呢>_<

算了再忍忍。

我要拿铜牌。

我一向言出必行,这就是我的忍道

——————————————

 1 #include <stdio.h>
 2 #include <string.h>
 3
 4 int a[105], c[105];
 5 int n, m;
 6 int dp[100005];
 7
 8 int mymax(int a, int b) {
 9     return a>b ? a:b;
10 }
11
12 void CompletePack(int c) {
13     int i;
14
15     for (i=c; i<=m; ++i)
16         dp[i] = mymax(dp[i], dp[i-c]);
17 }
18
19 void ZeroOnePack(int c) {
20     int i;
21
22     for (i=m; i>=c; --i)
23         dp[i] = mymax(dp[i], dp[i-c]);
24 }
25
26 void multipack(int c, int n) {
27     int k;
28     if (c*n >= m) {
29         CompletePack(c);
30         return ;
31     }
32     k = 1;
33     while (k < n) {
34         ZeroOnePack(k*c);
35         n -= k;
36         k *= 2;
37     }
38     ZeroOnePack(n*c);
39 }
40
41 int main() {
42     int i, total;
43
44     while (scanf("%d%d",&n,&m)!=EOF && (n||m)) {
45         memset(dp, 0, sizeof(dp));
46         dp[0] = 1;
47         for (i=1; i<=n; ++i)
48             scanf("%d", &a[i]);
49         for (i=1; i<=n; ++i)
50             scanf("%d", &c[i]);
51         for (i=1; i<=n; ++i)
52             multipack(a[i], c[i]);
53         total = 0;
54         for (i=1; i<=m; ++i)
55             if (dp[i])
56                 ++total;
57         printf("%d\n", total);
58     }
59
60     return 0;
61 }

时间: 2024-07-29 02:05:15

hdoj2844的相关文章