poj3260解题报告
来源:互联网 发布:教练技术 知乎 编辑:程序博客网 时间:2024/06/10 13:04
题目大意:
农夫John想到镇上买些补给。为了高效地完成任务,他想使硬币的转手次数最少。即使他交付的硬 币数与找零得到的的硬币数最少。 John想要买T(1<=T<=10000)样东西。有N(1<=n<=100)种货币参与流通,面值分别为V1,V2..Vn (1<=Vi<=120)。John有Ci个面值为Vi的硬币(0<=Ci<=10000)。我们假设店主有无限多的硬币, 并总按最优方案找零。
解题思路:
先来一次多重背包,上限要比t大才行,因为可以找钱,再来一发完全背包,因为找钱这个时候货币是无限的
代码:
#include<cstdio>
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=30000;
const int INF= 100000000;
int n,t,val[110],c[110],d[maxn],MAX,k,i,j;
int main()
{
//freopen("1.txt","r",stdin);
while(~scanf("%d%d",&n,&t))
{
MAX = 0;
for(i=1; i<=n; i++)
{
scanf("%d",&val[i]);
MAX = max(MAX,val[i]);
}
MAX*=MAX;
for(i=1; i<=n; i++)
scanf("%d",&c[i]);
for(i = 1; i<=t+MAX; i++)//初始化
d[i] = INF;
d[0] = 0;
for( i=1;i<=n;i++)//多重背包二进制优化法
{
k=1;
while(k<c[i])
{
for(j = t+MAX; j>=k*val[i]; j--)
d[j] = min(d[j],d[j-k*val[i]]+k);
c[i]-=k;
k=k*2;
}
for(j=MAX+t;j>=c[i]*val[i];j-- )
{d[j]=min(d[j],d[j-c[i]*val[i]]+c[i]);}
}
for( i=1;i<=n;i++)//完全背包找钱
for(j = t+MAX-val[i]; j>=0; j--)
d[j] = min(d[j],d[j+val[i]]+1);
if(d[t]==INF) cout<<-1<<endl;
else cout<<d[t]<<endl;
}
}
- poj3260解题报告
- poj3260
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 【背包】POJ3260
- Antiprime解题报告
- expr解题报告
- 华容道解题报告
- tju解题报告
- zju1062/pku1095解题报告
- UsacoGate解题报告 --- 序曲
- ZJU 2060 解题报告
- ZJU 1331 解题报告
- Android 开发实战
- 黑马程序员——Java基础:static关键字、单例设计模式
- protected权限问题
- OpenCV2邻域和模板操作
- Axis2
- poj3260解题报告
- Android-扫描二维码、生成二维码(Zxing库)
- 动态改变view的style
- spring MVC 2-helloword 入门
- jQuery收藏链接
- SPRING JDBC详细使用
- [Erlang]supervisor的child设置为dynamic详解
- Unity3D:NGUI Srollview子对象中有Button时,点击不能滚动
- Revo Uninstaller Pro v3.1.2 测试和评测: