呵呵哒……简直要被这道题玩死了好吗(掀桌
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