您的位置:首页 > 其它

暑假集训-训练 背包

2016-07-31 22:10 302 查看
B - FATE

Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Submit

Status

Practice

HDU 2159

Description

最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级。现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度。当忍耐度降到0或者0以下时,xhd就不会玩这游戏。xhd还说了他最多只杀s只怪。请问他能升掉这最后一级吗?

Input

输入数据有多组,对于每组数据第一行输入n,m,k,s(0 < n,m,k,s < 100)四个正整数。分别表示还需的经验值,保留的忍耐度,怪的种数和最多的杀怪数。接下来输入k行数据。每行数据输入两个正整数a,b(0 < a,b < 20);分别表示杀掉一只这种怪xhd会得到的经验值和会减掉的忍耐度。(每种怪都有无数个)

Output

输出升完这级还能保留的最大忍耐度,如果无法升完这级输出-1。

Sample Input

10 10 1 10

1 1

10 10 1 9

1 1

9 10 2 10

1 1

2 2

Sample Output

0

-1

1

B:二维完全背包

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=105;
int F[MAX][MAX],W[MAX],U[MAX];
int n,m,k,s;
void CompletePack(int ui,int vi,int wi)
{
for (int i=ui; i<=m; i++)
for (int j=vi; j<=s; j++)
F[i][j]=max(F[i][j],F[i-ui][j-vi]+wi);
}
int main()
{
while(cin>>n>>m>>k>>s)
{
memset(F,0,sizeof(F));
for (int i=1; i<=k; i++)
cin>>W[i]>>U[i];
for (int i=1; i<=k; i++)
CompletePack(U[i],1,W[i]);
if (n>F[m][s])
cout<<-1<<endl;
else
{
for (int i=0; i<=m; i++)
if (F[i][s]>=n)
{
cout<<(m-i)<<endl;
break;
}
}
}
return 0;
}


C - ACboy needs your help

Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Submit

Status

Practice

HDU 1712

Description

ACboy has N courses this term, and he plans to spend at most M days on study.Of course,the profit he will gain from different course depending on the days he spend on it.How to arrange the M days for the N courses to maximize the profit?

Input

The input consists of multiple data sets. A data set starts with a line containing two positive integers N and M, N is the number of courses, M is the days ACboy has.

Next follow a matrix A[i][j], (1<=i<=N<=100,1<=j<=M<=100).A[i][j] indicates if ACboy spend j days on ith course he will get profit of value A[i][j].

N = 0 and M = 0 ends the input.

Output

For each data set, your program should output a line which contains the number of the max profit ACboy will gain.

Sample Input

2 2

1 2

1 3

2 2

2 1

2 1

2 3

3 2 1

3 2 1

0 0

Sample Output

3

4

6

C:  分组背包

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=105;
int A[MAX][MAX],F[MAX];
int N,M;
int main()
{
while(cin>>N>>M)
{
memset(F,0,sizeof(F));
if (N==0&&M==0)
break;
for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
cin>>A[i][j];
for (int i=1; i<=N; i++)
for (int v=M; v>=0; v--)
for (int j=1; j<=v; j++)
F[v]=max(F[v],F[v-j]+A[i][j]);
cout<<F[M]<<endl;
}
return 0;
}


D - Cash Machine

Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%lld & %llu

Submit

Status

Practice

POJ 1276

Description

A Bank plans to install a machine for cash withdrawal. The machine is able to deliver appropriate @ bills for a requested cash amount. The machine uses exactly N distinct bill denominations, say Dk, k=1,N, and for each denomination Dk the machine has a supply of nk bills. For example,

N=3, n1=10, D1=100, n2=4, D2=50, n3=5, D3=10

means the machine has a supply of 10 bills of @100 each, 4 bills of @50 each, and 5 bills of @10 each.

Call cash the requested amount of cash the machine should deliver and write a program that computes the maximum amount of cash less than or equal to cash that can be effectively delivered according to the available bill supply of the machine.

Notes:

@ is the symbol of the currency delivered by the machine. For instance, @ may stand for dollar, euro, pound etc.

Input

The program input is from standard input. Each data set in the input stands for a particular transaction and has the format:

cash N n1 D1 n2 D2 … nN DN

where 0 <= cash <= 100000 is the amount of cash requested, 0 <=N <= 10 is the number of bill denominations and 0 <= nk <= 1000 is the number of available bills for the Dk denomination, 1 <= Dk <= 1000, k=1,N. White spaces can occur freely between the numbers in the input. The input data are correct.

Output

For each set of data the program prints the result to the standard output on a separate line as shown in the examples below.

Sample Input

735 3 4 125 6 5 3 350

633 4 500 30 6 100 1 5 0 1

735 0

0 3 10 100 10 50 10 10

Sample Output

735

630

0

0

Hint

The first data set designates a transaction where the amount of cash requested is @735. The machine contains 3 bill denominations: 4 bills of @125, 6 bills of @5, and 3 bills of @350. The machine can deliver the exact amount of requested cash.

In the second case the bill supply of the machine does not fit the exact amount of cash requested. The maximum cash that can be delivered is @630. Notice that there can be several possibilities to combine the bills in the machine for matching the delivered cash.

In the third case the machine is empty and no cash is delivered. In the fourth case the amount of cash requested is @0 and, therefore, the machine delivers no cash.

D:多重背包

include

include

include

include

include

include

include

include

include

include

include

include

using namespace std;

const int MAX=100005;

int Cash,N,M[15],C[15],W[15],F[MAX];

void ZeroOnePack(int Ci,int Wi)

{

for (int i=Cash;i>=Ci;i–)

F[i]=max(F[i],F[i-Ci]+Wi);

}

void CompletePack(int Ci,int Wi)

{

for (int i=Ci;i<=Cash;i++)

F[i]=max(F[i],F[i-Ci]+Wi);

}

void MultiplePack(int Ci,int Wi,int Mi)

{

if (Cash<=Ci*Mi)

CompletePack(Ci,Wi);

else

{

int k=1;

while(k<=Mi)

{

ZeroOnePack(k*Ci,k*Wi);

Mi-=k;

k=2*k;

}

ZeroOnePack(Mi*Ci,Mi*Wi);

}

}

int main()

{

while(cin>>Cash>>N)

{

memset(F,0,sizeof(F));

for (int i=1;i<=N;i++)

{

cin>>M[i]>>C[i];

W[i]=C[i];

}

for (int i=1;i<=N;i++)

MultiplePack(C[i],W[i],M[i]);

cout<

E:最小价值完全背包 全初始化为INF F[0]=0;

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=10005;
const int INF=99999999;
int Cash,N,C[505],W[505],F[MAX],E,X;
void CompletePack(int Ci,int Wi)
{
for (int i=Ci;i<=Cash;i++)
F[i]=min(F[i],F[i-Ci]+Wi);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
for (int i=0;i<MAX;i++) F[i]=INF;
F[0]=0;
scanf("%d%d",&E,&X);
Cash=X-E;
scanf("%d",&N);
for (int i=1;i<=N;i++)
scanf("%d%d",&W[i],&C[i]);
for (int i=1;i<=N;i++)
CompletePack(C[i],W[i]);
if (F[Cash]==INF) cout<<"This is impossible."<<endl;
else cout<<"The minimum amount of money in the piggy-bank is "<<F[Cash]<<"."<<endl;
}
return 0;
}


G - 0/1背包练手

Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Submit

Status

Practice

HDU 2955

Description

The aspiring Roy the Robber has seen a lot of American movies, and knows that the bad guys usually gets caught in the end, often because they become too greedy. He has decided to work in the lucrative business of bank robbery only for a short while, before retiring to a comfortable job at a university.

For a few months now, Roy has been assessing the security of various banks and the amount of cash they hold. He wants to make a calculated risk, and grab as much money as possible.

His mother, Ola, has decided upon a tolerable probability of getting caught. She feels that he is safe enough if the banks he robs together give a probability less than this.

Input

The first line of input gives T, the number of cases. For each scenario, the first line of input gives a floating point number P, the probability Roy needs to be below, and an integer N, the number of banks he has plans for. Then follow N lines, where line j gives an integer Mj and a floating point number Pj .

Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .

Output

For each test case, output a line with the maximum number of millions he can expect to get while the probability of getting caught is less than the limit set.

Notes and Constraints

0 < T <= 100

0.0 <= P <= 1.0

0 < N <= 100

0 < Mj <= 100

0.0 <= Pj <= 1.0

A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.

Sample Input

3

0.04 3

1 0.02

2 0.03

3 0.05

0.06 3

2 0.03

2 0.03

3 0.05

0.10 3

1 0.03

2 0.02

3 0.05

Sample Output

2

4

6

G: 01背包
F[i]=max(F[i],F[i-m]*p); 将题目给出的被抓到的概率转化为不被抓到的概率.F[i]表示在抢到i钱的时候不被抓到的概率.只要不被抓到的概率大于等于(1-P)即可.

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=10000+5;
double F[MAX],Pr[105],P;
int M[105],N,T,sumMo;
void ZeroOnePack(int m,double p)
{
for (int i=sumMo; i>=m; i--)
F[i]=max(F[i],F[i-m]*p);
}
int main()
{
cin>>T;
while(T--)
{
cin>>P>>N;
P=1.00-P;
memset(F,0,sizeof(F));
F[0]=1.0;
sumMo=0;
for (int i=1; i<=N; i++) cin>>M[i],sumMo+=M[i],cin>>Pr[i],Pr[i]=1.00-Pr[i];
for (int i=1; i<=N; i++) ZeroOnePack(M[i],Pr[i]);
for (int i=sumMo; i>=0; i--)
if (F[i]>=P)
{
cout<<i<<endl;
break;
}
}
return 0;
}


H - 0/1背包练手

Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Submit

Status

Practice

HDU 2602

Description

Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …

The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?

Input

The first line contain a integer T , the number of cases.

Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.

Output

One integer per line representing the maximum of the total value (this number will be less than 2 31).

Sample Input

1

5 10

1 2 3 4 5

5 4 3 2 1

Sample Output

14

H: 01背包

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=1000+5;
int F[MAX],C[MAX],W[MAX];
int N,V;
void ZeroOnePack(int c,int w)
{
for (int i=V; i>=c; i--)
F[i]=max(F[i],F[i-c]+w);
}
int main()
{
int T;
cin>>T;
while(T--)
{
memset(F,0,sizeof(F));
cin>>N>>V;
for (int i=1;i<=N;i++) cin>>W[i];
for (int i=1;i<=N;i++) cin>>C[i];
for (int i=1;i<=N;i++)
ZeroOnePack(C[i],W[i]);
cout<<F[V]<<endl;
}
return 0;
}


I - The more, The Better

Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Submit

Status

Practice

HDU 1561

Description

ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗?

Input

每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。

Output

对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。

Sample Input

3 2

0 1

0 2

0 3

7 4

2 2

0 1

0 4

2 1

7 1

7 6

2 2

0 0

Sample Output

5

13

I:树形dp 依赖背包

方程dp[k][j]=max(dp[k][j],dp[k][j-kk]+dp[t[k][i]][kk])
dp[k][1]=val[k],因为选一个点的话必须选自己
dp[i][j]表示以i为根的子树选择j个点所能达到的最优值

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=200+5;
vector<int> pic[MAX];
int F[MAX][MAX],A[MAX];
int N,M,a,b;
void dfs(int x,int m)
{
F[x][1]=A[x];
for (int i=0;i<(int)pic[x].size();i++)
{
if (m>1)
dfs(pic[x][i],m-1);
for (int j=m;j>=1;j--)
{
for (int k=1;k<=j;k++)
F[x][j+1]=max(F[x][j+1],F[x][j+1-k]+F[pic[x][i]][k]);
}
}
}
int main()
{
while(scanf("%d%d",&N,&M))
{
memset(F,-1,sizeof(F));
memset(A,0,sizeof(A));
for (int i=0;i<MAX;i++) pic[i].clear();
if (N==0&&M==0) break;
for (int i=1;i<=N;i++)
{
scanf("%d%d",&a,&A[i]);
pic[a].push_back(i);
}
dfs(0,M+1);
cout<<F[0][M+1]<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: