poj1360(完全背包+多重背包+鸽巢原理)
来源:互联网 发布:解数独算法 编辑:程序博客网 时间:2024/05/18 18:21
题意,fj去买价格为t的物品, shopkeeper只接受n种货币,价值分别vi,对于每种货币fj有ci个,但 shopkeeper都有无数个这种货币。求最少使用多少货币完成交易。
对于fj,进行一次多重背包,
对 shopkeeper,进行一次完全背包。
最重要的是要考虑上界,
鸽巢原理:
fj最多支付maxv*maxv+t, shopkeeper最多找零maxv *maxv。
证明:
如果fjJohn的付款数大于了maxv*maxv+m,即使用的货币数超过maxv,由鸽巢原理,
必然有若干个货币组合起来是maxv的倍数,(因为一个数对maxv取模最多maxv种答案)
那么这些货币肯定可以在给钱的时候少给一些,从而推出这样的方案肯定不是最优方案。
#include <iostream>#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <stack>#include <vector>#include <string.h>#include <queue>#define msc(X) memset(X,-1,sizeof(X))#define ms(X) memset(X,0,sizeof(X))typedef long long LL;using namespace std;const int inf=0x3f3f3f3f;const int maxt=24400;int dp[maxt+10005];int wdp[maxt+5];int v[101],c[101];int main(int argc, char const *argv[]){ int n,t,mt=0; scanf("%d %d",&n,&t); for(int i=0;i<n;i++) { scanf("%d",v+i); mt=max(mt,v[i]); } for(int i=0;i<n;i++) scanf("%d",c+i); for(int i=1;i<=mt*mt+t;i++) dp[i]=inf; for(int i=1;i<=mt*mt;i++) wdp[i]=inf; dp[0]=wdp[0]=0; for(int i=0;i<n;i++)//完全背包 for(int j=v[i];j<=mt*mt;j++) wdp[j]=min(wdp[j],wdp[j-v[i]]+1); for(int i=0;i<n;i++) { if(c[i]*v[i]>=mt*mt+t){ for(int j=v[i];j<=mt*mt+t;j++) dp[j]=min(dp[j],dp[j-v[i]]+1); } else{ for(int bit=1;bit<c[i];bit<<=1) { for(int j=mt*mt+t;j>=bit*v[i];j--) dp[j]=min(dp[j],dp[j-bit*v[i]]+bit); c[i]-=bit; } for(int j=mt*mt+t;j>=c[i]*v[i];j--) dp[j]=min(dp[j],dp[j-c[i]*v[i]]+c[i]); } } int ans=dp[t]; for(int j=t+1;j<=mt*mt+t;j++) ans=min(ans,dp[j]+wdp[j-t]); if(ans<inf) printf("%d\n",ans ); else puts("-1"); return 0;}/*3 109 12 53 1 13 148 4 1012 1 1*/
0 0
- poj1360(完全背包+多重背包+鸽巢原理)
- 背包问题(01背包,完全背包,多重背包)
- 背包问题(01背包,完全背包,多重背包)
- 背包(01背包、完全背包、多重背包)问题总结
- 背包模板(01背包,完全背包,多重背包)
- 背包问题(01背包,完全背包,多重背包)
- 背包问题(01背包 + 完全背包 + 多重背包)
- 背包问题(01背包,完全背包,多重背包)
- 背包问题模板(01背包,完全背包,多重背包)
- 经典背包问题----(01背包、完全背包、多重背包)
- poj3260 (多重背包+完全背包)
- poj1787-多重背包(基于完全背包)
- hdu2844 完全背包+多重背包(经典)
- DP总结(1) 01背包 完全背包 多重背包
- 01背包模板、完全背包 and 多重背包(模板)
- 动态规划总结(01背包 完全背包 多重背包)
- 动态规划初步( 01 背包、完全背包、多重背包)
- 01背包模板、完全背包 and 多重背包(模板)
- 如何学习编程
- PopUpWindiw的背景虚化以及显示listview
- Android内存优化之OOM
- 格式化和验证Hadoop,Spark等xml配置文件的工具xmllint
- 使用数组和指针的形式实现冒泡排序,并优化。bubble_sort();
- poj1360(完全背包+多重背包+鸽巢原理)
- Spark的缓存管理解析
- 无刷新form表单
- MAC Ruby版本需要升级至2.2.2以上
- C语言单链表的应用--档案管理系统
- C++类的实例化的两种方法
- openvswitch 2.5 + centos 7
- (c#)AutoCAD二次开发调试时,netload后,输入命令,却显示为未知命令
- httpurlconnection_get_post