HDU 2844 Coins(多重背包+二进制优化)

 

 

          Coins

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3424    Accepted Submission(s): 1345


Problem Description
Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One day Hibix opened purse and found there were some coins. He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch.

You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins.
 

 

Input
The input contains several test cases. The first line of each test case contains two integers n(1 ≤ n ≤ 100),m(m ≤ 100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1 ≤ Ai ≤ 100000,1 ≤ Ci ≤ 1000). The last test case is followed by two zeros.
 

 

Output
For each test case output the answer on a single line.
 

 

Sample Input
3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0
 

 

Sample Output
8
4
 

 

Source
 

 

Recommend
gaojie
 
 
 
分析:多重背包问题.有n个物品(硬币),每个物品有价值value[i],每个物品数量限制为num[i].
这道题要求的是用所有的硬币在1到m的范围内最多能够组合成多少种价值.每种硬币有数量的限制.
对于每种硬币而言:
if 价值×数量>=m
       then 取这种硬币的次数相当于无限制,可以考虑成完全背包
else
       then 考虑成0-1背包(二进制优化),就是把这种硬币的value和num组合出0-1背包可能出现的状态(可以去看背包九讲)

(对于num,类似于编码.当2^n<=num/2时:k=2^n(n=0,1,2,……)表示状态,对应下来就是二进制的某一位数是1,然后还有一个状态就是k>num/2的时候啦,num+1-k,这样下来就可以用k来组合枚举出从1->num的所有可能了.然后对于k,单位价值和大小都乘上k之后就变成了一个01背包).

 

对于多重背包问题可以这样解: 
MultiplePack(cost,weight,amount)
{
    if(cost*weight>=V)
      CompletePack(cost,weight)
    else
    {
       for(int i=1;i<amount;i<<1)
        {
            ZeroOnePack(i*cost,i*weight);
            amount-=i;
        }
        ZeroOnePack(amount*cost,amount*weight)
    }
}

这道题的cost和weight是同一种量.

 

 

#include<iostream>
using namespace std;
int dp[100010];
int a[110],c[110];
int n,m;
void ZeroOnePack(int c,int w)//01背包
{
    for(int i=m;i>=c;i--)
        dp[i]=dp[i]|dp[i-c];
/*等价于dp[i]=Max(dp[i],dp[i-c]);*/; } void CompletePack(int c,int w)//完全背包 { for(int i=c;i<=m;i++) dp[i]=dp[i]|dp[i-c]; }
void MutiplePack(int c,int w)//多重背包 { int temp; if(c*w>=m)//如果物品的总花费大于背包容量就利用完全背包解决 CompletePack(c,w); else//否则利用01背包解决(二进制思想优化) { temp=w; for(int i=1;i<=temp;i<<2) { ZeroOnePack(i*c,i*w); temp-=i; } ZeroOnePack(temp*c,temp*w); } } int main() { int i; while(scanf("%d%d",&n,&m),n||m) { memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=n;i++) scanf("%d",&c[i]); dp[0]=1; for(i=1;i<=n;i++) MutiplePack(a[i],c[i]); int ans=0; for(i=1;i<=m;i++) if(dp[i]) ans++; printf("%d\n",ans); } return 0; }

 

转载于:https://www.cnblogs.com/Su-Blog/archive/2012/08/19/2646558.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Eclipse二进制文件是指由Eclipse集成开发环境生成的可执行文件。在Linux下,Eclipse生成的二进制文件通常是没有扩展名的,如上述引用所示。在使用Eclipse编译和运行项目时,如果项目名包含扩展名(例如.hdu.c),则Eclipse可能无法正确识别该文件为二进制可执行文件。 这可能导致在运行时出现找不到二进制文件的错误。解决办法有两种:一是避免使用带有扩展名的项目名,另一种是手动创建一个运行配置,将命令写死以确保正确识别为二进制文件。 需要注意的是,上述讨论中的EclipseParser库是一个用于验证和读取Eclipse二进制文件内容的DLL库,它是通过按照二进制格式编写的。这个库可以验证和读取Eclipse二进制文件中的EGRID、INIT、UNRST等内容。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [linux下eclipse c++运行不了提示找不到二进制文件的解决方法](https://blog.csdn.net/bjrxyz/article/details/8974483)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Eclipse油藏数值模拟软件的二进制文件格式解析](https://blog.csdn.net/slofslb/article/details/119176891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值