(完全背包)The cicerone’s abacus

The cicerone’s abacus

时间限制(普通/Java):1000MS/3000MS              运行内存限制:65536KByte
总提交:1015                测试通过:337

描述

 

 

输入

The input file contains multiple test cases. For each case the first line includes a positive integer n representing the number of sightseers who intend to buy souvenirs. The second line includes n integers each of which is the maximum budget (positive integer and less than 2000) each sightseer plans to spend. There is a positive integer m (m<101) in the following line indicating the categories of the goods. Then comes m lines. Each line has two integers. The first is the price p of the goods (p<1000) and the second is the value of the relevant kickback (no more than 0.2p).

输出

For each test case output one line contains the maximum value of the kickback the cicerone can obtain.

样例输入

3
200 300 300
5
12 2
20 4
30 5
50 5
100 18

样例输出

160

题目来源

NUAA

 

Currently for the requirement of the sightseers, many cicerones often take them to shopping for some souvenirs in addition to the introduction of the local culture and historic sites. Some souvenir shops give the cicerones who bring sightseers some kickbacks in order to make them bring more. The amount of the kickback is determined by the value of the goods. The shops usually list the values of the goods and the relevant kickbacks for the cicerones to make them clear of the reward they can earn from each kind of goods.

Assume the cicerone has known the maximum amount of money every sightseer intends to spend and the trust of the sightseers on him. The sightseers will buy all souvenirs in any quantity recommended by the cicerone only if their maximum budgets are kept. Before going to the shop, the cicerone starts calculating which goods he should recommend to which sightseer so as to make himself obtain the maximum kickbacks. Unfortunately, this is such a hard problem for him that he never works it out.

    Luckily, the cicerone meets you who is good at programming, so he hopes you can program to finish this job. Assume the shop has enough quantity of every goods to meet the shopping requirement of all sightseers.

 

 

#include<iostream>

#include<string>

using namespace std;

int dn[101][2001];

int price[101];

int person[2001];

int back[101];

int main()

{

int T,m,i,j,k;

while(cin>>T)

{

for(i=0;i<T;i++)

cin>>person[i];

cin>>m;

for(j=0;j<m;j++)

cin>>price[j]>>back[j];

 

        int sum=0,max;

for(int s=0;s<T;s++)

{

memset(dn,0,sizeof(dn));

for(i=1;i<=m;i++)

for(j=1;j<=person[s];j++)

{

max=0;

//max=dn[i-1][j]也可以

for(k=0;k<=j/price[i-1];k++)

{

if(dn[i-1][j-k*price[i-1]]+k*back[i-1]>max)

max=dn[i-1][j-k*price[i-1]]+k*back[i-1];

}

dn[i][j]=max;

}

sum+=dn[m][person[s]];

}

cout<<sum<<endl;

}

}

 完全背包问题

题目

有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

基本思路

这个问题非常类似于01背包问题,所不同的是每种物品有无限件。也就是从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取0件、取1件、取2件……等很多种。如果仍然按照解01背包时的思路,令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值。仍然可以按照每种物品不同的策略写出状态转移方程,像这样:

f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v}

这跟01背包问题一样有O(VN)个状态需要求解,但求解每个状态的时间已经不是常数了,求解状态f[i][v]的时间是O(v/c[i]),总的复杂度可以认为是O(V*Σ(V/c[i])),是比较大的。

将01背包问题的基本思路加以改进,得到了这样一个清晰的方法。这说明01背包问题的方程的确是很重要,可以推及其它类型的背包问题。但我们还是试图改进这个复杂度。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值