poj - 1742 Coins

楼教主的“男人八题”之一,多重背包问题,che男让我用单调队列来做,可是我觉得单调队列太头疼,就搜了另外一种思路,然后自己写了一个。于是诡异的事情发生了,该题的Disscus里面也有一个我和的思路一模一样的代码,代码也几乎一模一样,连开的数组大小都是一样的,想说我不是抄的都没人信啊,郁闷。

这是Disscus里面的:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 bool can_pay[100005]; 
 7 int use_ai[100005];    
 8 int Ai[105], Ci[105];
 9 int n, m, ans;
10 
11 int coins();
12 
13 int main()
14 {
15     int i;
16     while(scanf("%d%d", &n, &m), n || m)
17     {
18         memset(can_pay, false, sizeof(can_pay));
19         can_pay[0] = true;
20         for(i = 0; i < n; ++i)
21             scanf("%d", &Ai[i]);
22         for(i = 0; i < n; ++i)
23             scanf("%d", &Ci[i]);
24         coins();
25     }
26     return 0;
27 }
28 
29 int coins()
30 {
31     int i, j;
32     ans = 0;
33     for(i = 0; i < n; ++i)
34     {
35         memset(use_ai, 0, sizeof(use_ai));
36         for(j = Ai[i]; j <= m; ++j)
37         {
38                 if(!can_pay[j] && can_pay[j - Ai[i]] && use_ai[j - Ai[i]] < Ci[i])
39                 {
40                     can_pay[j] = true;
41                     use_ai[j] = use_ai[j - Ai[i]] + 1;
42                     ++ans;
43                 }
44         }
45     }
46     printf("%d\n", ans);
47     return 0;
48 }

这是我的:

 1 #include <stdio.h>
 2 #include <string.h>
 3 int a[105],c[105];
 4 bool M[100005];
 5 int cnt[100005];
 6 int main()
 7 {
 8     int m,n,i,j,ans;
 9     while(scanf("%d%d",&n,&m),m&&n)
10     {
11         for(i = 0; i < n; i++)
12             scanf("%d",&a[i]);
13         for(i = 0; i < n; i++)
14             scanf("%d",&c[i]);
15         M[0] = 1;
16         ans = 0;
17         for(i = 0; i < n; i++)
18         {
19             memset(cnt,0,sizeof(int) *m);
20             for(j = 0; j <= m-a[i] && M[j]; j++)
21             {
22                 if(cnt[j] >= c[i]) break;
23                 if(!M[j+a[i]])
24                 {
25                     M[j+a[i]] = 1;
26                     cnt[j+a[i]] = cnt[j]+1;
27                     ans++;
28                 }
29             }
30         }
31         printf("%d\n",ans);
32         memset(M,0,sizeof(bool ) *m);
33     }
34     return 0;
35 }

 

为了证明我真的是自己写的,我把细节说一下,用Google搜“多重背包O(VN)”,打开第一条“曙光”的新浪博客,里面的思路就是我找到的了。不过我真的不是抄的,因为我的代码老是WA,这让我极度郁闷,几乎一模一样的代码,怎么我的就WA呢?坏就坏在这个“几乎”上,可以不夸张的说,两份代码只要有一个字节不一样,结果都可能天差地别。我一次又一次地提了十几回,终于找到了问题。

我的代码一共有3个问题。

1. 20行的“&&M[j]”,我有时候会把for(){ if() }的形式里if的条件直接加到for里面,事实证明,这不是个好习惯,这题要把这步放到for里面才行;

2. 22行的break,这样提前退出会漏掉一些情况;

3. 里面两个memset的规模,本来我觉得这样也没错,可是交上去就是WA,改成全部就行了,至于位置不重要,for的头和尾都行。

本来这题就是卡时间的,看到别人已经把复杂度缩到O(VN)了,还要绞尽脑汁地进行常数优化,而我的思路只要1000+ms,我很是得意,可是一看排行榜,一群300-ms的bug般的存在的大牛就在那里,不禁膜拜之。

转载于:https://www.cnblogs.com/lzxskjo/archive/2012/07/20/2601841.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值