Coins

http://acm.hdu.edu.cn/showproblem.php?pid=2844

一道水DP居然被我写成这样,我真是人才,卡了一下午+一晚上,找出问题来了,与一种想去屎的冲动。

算了说一说题意吧,题目意思就是有  n 种硬币,每种对应多少个,这些硬币有多少种组和的值(满足和小于等于m)

提议就是二维背包+2进制优化 

我以为超时的,结果数据很弱。但是自己写傻逼了 2进制优化的时候tmp=tmp<<1,写成了tmp<<1,自己造的一组极端数据跑了43.7亿次,本来是可以只跑2千万次的。傻逼不解释。

代码是

#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <memory.h>
#define maxn 100005
using namespace std;
int dp[maxn];
int values[105],number[105];
int main()
{
    //freopen("in.txt","r",stdin);
    int num,value,ans,i,j;
    int count;
    while(~scanf("%d%d",&num,&value)&&!(num==0&&value==0))
    {
        memset(dp,0,sizeof dp);ans=0;dp[0]=1,count=0;
        for(i=1;i<=num;i++)scanf("%d",values+i);
        for(i=1;i<=num;i++)scanf("%d",number+i);
        for(i=1;i<=num;i++)
        {
            int tmp=1,tot=0;
            while(tmp+tot<=number[i])
            {
                for(j=value;j>=values[i]*tmp;j--)
                {
                    if(dp[j]<dp[j-values[i]*tmp]){dp[j]=1;ans++;}
                }
                tot+=tmp;tmp=tmp<<1;//开始写的是 tmp<<1;找死我了。
            }
            if(tot<number[i])
            {
                for(j= value;j>=values[i]*(number[i]-tot);j--)
                {
                    if(dp[j]<dp[j-values[i]*(number[i]-tot)]){dp[j]=1;ans++;}
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
现在附上极端数据:100 100000
42 18468 6335 26501 19170 15725 11479 29359 26963 24465 5706 28146 23282 16828 9962 492 2996 11943 4828 5437 32392 14605 3903 154 293 12383 17422 18717 19719 19896 5448 21727 14772 11539 1870 19913 25668 26300 17036 9895 28704 23812 31323 30334 17674 4665 15142 7712 28254 6869 25548 27645 32663 32758 20038 12860 8724 9742 27530 779 12317 3036 22191 1843 289 30107 9041 8943 19265 22649 27447 23806 15891 6730 24371 15351 15007 31102 24394 3549 19630 12624 24085 19955 18757 11841 4967 7377 13932 26309 16945 32440 24627 11324 5538 21539 16119 2083 22930 16542
834 116 640 659 705 931 978 307 674 387 22 746 925 73 271 830 778 574 98 513 987 291 162 637 356 768 656 575 32 53 351 151 942 725 967 431 108 192 8 338 458 288 754 384 946 910 210 759 222 589 423 947 507 31 414 169 901 592 763 656 411 360 625 538 549 484 596 42 603 351 292 837 375 21 597 22 349 200 669 485 282 735 54 1000 419 939 901 789 128 468 729 894 649 484 808 422 311 618 814 515

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值