动态规划——背包基础题

1414: 集装箱装载

时间限制: 1 Sec   内存限制: 128 MB
提交: 21   解决: 13
[ 提交][ 状态][ 讨论版]

题目描述

有一批共 n 个集装箱要装上艘载重量为 c 的轮船,其中集装箱 i 的重量为 wi 。找出一种最优装载方案,将轮船尽可能装满,即在装载体积不受限制的情况下,将尽可能重的集装箱装上轮船。

输入

第一行有2个正整数ncn是集装箱数,c是轮船的载重量。第2行中有n个正整数,表示集装箱的重量(0<n<10000,0<c<32767)。

输出

计算出的最大装载重量输出。

样例输入

5 10
7 2 6 5 4

样例输出

10

提示

来源

#include<iostream>
using namespace std;
int main()
{
	int n,c,a[10005];
	int dp[10005]={0};
	while(cin>>n>>c)
	{
		for(int i=0;i<n;i++){
			cin>>a[i]; 
			for(int j=c;j>=a[i];j--)
			dp[j]=min(dp[j],dp[j-a[i]]+a[i]);
		}
		cout<<dp[c];
	}
}

1415: 货币系统

时间限制: 1 Sec   内存限制: 128 MB
提交: 23   解决: 10
[ 提交][ 状态][ 讨论版]

题目描述

给你一个n种面值的货币系统,求组成面值为m的货币有多少种方案。样例:设n=3,m=10,要求输入和输出的格式如下:

输入

第一行两个整数n,m(m<=5000)
以下n行,每行一个整数,第i+1行为第i种货币的面值

输出

一个整数,为方案数

样例输入

3 10
1
2
5

样例输出

10
完全背包思想
#include<iostream>
#include<string.h>
using namespace std;
long long a[5005];//数比计较大 
int main()
{
	int n,m,k;
	while(cin>>n>>m)
	{
		a[0]=1;
		for(int i=0;i<n;i++)
		{
			cin>>k;
			for(int j=k;j<=m;j++)
			a[j]+=a[j-k];
		}
		cout<<a[m];
	}
}

1416: 竞赛总分

时间限制: 1 Sec   内存限制: 128 MB
提交: 12   解决: 11
[ 提交][ 状态][ 讨论版]

题目描述

学生在我们USACO的竞赛中的得分越多我们越高兴。
我们试着设计我们的竞赛以便人们能尽可能的多得分,这需要你的帮助。
我们可以从几个种类中选取竞赛的题目,这里的一个"种类"是指一个竞赛题目的集合,解决集合中的题目需要相同多的时间并且能得到相同的分数。你的任务是写一个程序来告诉USACO的职员,应该从每一个种类中选取多少题目,使得解决题目的总耗时在竞赛规定的时间里并且总分最大。输入包括竞赛的时间,M(1 <= M <= 10,000)(不要担心,你要到了训练营中才会有长时间的比赛)和N,"种类"的数目1 <= N <= 10,000。后面的每一行将包括两个整数来描述一个"种类":
第一个整数说明解决这种题目能得的分数(1 <= points <= 10000),第二整数说明解决这种题目所需的时间(1 <= minutes <= 10000)。
你的程序应该确定我们应该从每个"种类"中选多少道题目使得能在竞赛的时间中得到最大的分数。
来自任意的"种类"的题目数目可能是任何非负数(0或更多)。
计算可能得到的最大分数。

输入

第 1 行: M, N--竞赛的时间和题目"种类"的数目。
第 2-N+1 行: 两个整数:每个"种类"题目的分数和耗时。

输出

单独的一行包括那个在给定的限制里可能得到的最大的分数。

样例输入

300 4
100 60
250 120
120 100
35 20

样例输出

605

提示

来源

#include<iostream>
using namespace std;
#define N 10000+5
int main()
{
    int tm,n;
    cin>>tm>>n;
    int score[N],time[N];
    int dp[N]={0};
    for(int i=0;i<n;i++)
    cin>>score[i]>>time[i];
    for(int i=0;i<n;i++)
        for(int j=time[i];j<=tm;j++)
        {
            if(dp[j-time[i]]+score[i]>dp[j])
            dp[j]=dp[j-time[i]]+score[i];
        }
    cout<<dp[tm];
}

1417: 最小乘车费用

时间限制: 1 Sec   内存限制: 128 MB
提交: 5   解决: 5
[ 提交][ 状态][ 讨论版]

题目描述

某条街上每一公里就有一汽车站,乘车费用如下表:

公里数

1

2

3

4

5

6

7

8

9

10

费用

12

21

31

40

49

58

69

79

90

101

而一辆汽车从不行驶超过10公里。某人想行驶n公里,假设他可以任意次换车,请你帮他找到一种乘车方案使费用最小(10公里的费用比1公里小的情况是允许的,且汽车不能往回坐)。
编一程序:
从文件中读入对乘车费用的描述;算出最小的价格;

输入

输入文件共两行,第一行为10个不超过100的整数,依次表示行驶1~10公里的费用,相邻两数间用空格隔开;第二行为某人想要行驶的公里数。

输出

输出文件仅一行包含一个整数,表示该测试点的最小费用。

样例输入

12 21 31 40 49 58 69 79 90 101
15

样例输出

147

提示

来源


#include<iostream>
#include<string.h>
using namespace std;
int main()
{
	int a[11],k;
	int dp[5005];
	memset(dp,101,sizeof(dp));
	dp[0]=0;
	for(int i=1;i<=10;i++)
	cin>>a[i];
	cin>>k;
	for(int i=1;i<=10;i++)
		for(int j=i;j<=k;j++)
		dp[j]=min(dp[j],dp[j-i]+a[i]);
	cout<<dp[k]<<endl;
}

1441: 完全背包问题

时间限制: 1 Sec  内存限制: 128 MB
提交: 21  解决: 10
[ 提交][ 状态][ 讨论版]

题目描述

设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。

输入

第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);

第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

输出

仅一行,一个数,表示最大总价值。

样例输入

10 4
2 1
3 3
4 5
7 9

样例输出

max=12
#include<stdio.h>
#include<iostream>
#include<string.h> 
using namespace std;
#define N 30+5
int main()
{
	int n,m;
	int a[N],b[N],d[205]; 
	while(cin>>m>>n)
	{
		memset(d,0,sizeof(d));
		for(int i=0;i<n;i++)
		cin>>a[i]>>b[i];
		for(int i=0;i<n;i++)
			for(int j=a[i];j<=m;j++)
			d[j]=max(d[j],d[j-a[i]]+b[i]);
		cout<<"max="<<d[m]<<endl;
	}
}

悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 34540    Accepted Submission(s): 14544


Problem Description
急!灾区的食物依然短缺!
为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。
请问:你用有限的资金最多能采购多少公斤粮食呢?

后记:
人生是一个充满了变数的生命过程,天灾、人祸、病痛是我们生命历程中不可预知的威胁。
月有阴晴圆缺,人有旦夕祸福,未来对于我们而言是一个未知数。那么,我们要做的就应该是珍惜现在,感恩生活——
感谢父母,他们给予我们生命,抚养我们成人;
感谢老师,他们授给我们知识,教我们做人
感谢朋友,他们让我们感受到世界的温暖;
感谢对手,他们令我们不断进取、努力。 
同样,我们也要感谢痛苦与艰辛带给我们的财富~


 

Input
输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。
 

Output
对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。
 

Sample Input
 
     
18 22 100 44 100 2
 
Sample Output
 
     
400
 

Author
lcy
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   1114  2602  2159  1171  1059 
 
 
#include<stdio.h>
#include<iostream>
#include<string.h> 
using namespace std;
#define N 105
int main()
{
	int n,m,i,j,k;
	int a[N],b[N],c[N],d[205]; 
	int t;
	cin>>t;
	while(t--)
	{
		cin>>m>>n;
		memset(d,0,sizeof(d));
		for(i=0;i<n;i++)
		cin>>a[i]>>b[i]>>c[i];
		for(i=0;i<n;i++)
		 for(j=0;j<c[i];j++)
		   for(k=m;k>=a[i];k--)
		   d[k]=max(d[k],d[k-a[i]]+b[i]);
		cout<<d[m]<<endl;
	}
}

1435: 混合背包

时间限制: 1 Sec  内存限制: 128 MB
提交: 8  解决: 8
[ 提交][ 状态][ 讨论版]

题目描述

      一个旅行者有一个最多能用V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

输入

第一行:二个整数,V(背包容量,V<=200),N(物品数量,N<=30);

第2..N+1行:每行三个整数Wi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数(Pi)。

输出

仅一行,一个数,表示最大总价值。

样例输入

10 3
2 1 0
3 3 1
4 5 4

样例输出

11

提示

来源

动态规划-背包问题 

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
struct bag{
	int wi;
	int pi;
	int num;
}a[35];
int dp[205];
int main()
{
	int v,n;
	while(cin>>v>>n)
	{
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
		cin>>a[i].wi>>a[i].pi>>a[i].num;
		for(int i=1;i<=n;i++)
		{
			if(a[i].num==1)
			{
				for(int j=v;j>=a[i].wi;j--)
				dp[j]=max(dp[j],dp[j-a[i].wi]+a[i].pi);
			}
			else if(a[i].num==0){
				for(int j=a[i].wi;j<=v;j++)
				dp[j]=max(dp[j],dp[j-a[i].wi]+a[i].pi);
			}
			else {
				  for(int k=1;k<=a[i].num;k++)
				  for(int j=v;j-k*a[i].wi>=0;j--)
				  {
				  	dp[j]=max(dp[j],dp[j-a[i].wi]+a[i].pi);
				  }
			}
		 } 
	    cout<<dp[v]<<endl;	
	}
}

1428: 庆功会

时间限制: 1 Sec  内存限制: 128 MB
提交: 5  解决: 5
[ 提交][ 状态][ 讨论版]

题目描述

      为了庆贺班级在校运动会上取得全校第一名成绩,班主任决定开一场庆功会,为此拨款购买奖品犒劳运动员。期望拨款金额能购买最大价值的奖品,可以补充他们的精力和体力。

输入

第一行二个数n(n<=500),m(m<=6000),其中n代表希望购买的奖品的种数,m表示拨款金额。

接下来n行,每行3个数,v、w、s,分别表示第I种奖品的价格、价值(价格与价值是不同的概念)和购买的数量(买0件到s件均可),其中v<=100,w<=1000,s<=10。

输出

第一行:一个数,表示此次购买能获得的最大的价值(注意!不是价格)。

样例输入

5 1000;80 20 4;40 50 9;30 50 7;40 30 6;20 20 1

样例输出

1040
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int dp[6005];
struct prize{
	int v,w,s;
}a[505];
int main(){
	int n,m;
	while(cin>>n>>m)
	{
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
		cin>>a[i].v>>a[i].w>>a[i].s;
		for(int i=1;i<=n;i++)
		{
			for(int k=1;k<=a[i].s;k++)
			{
				for(int j=m;j>=a[i].v;j--)
				dp[j]=max(dp[j],dp[j-a[i].v]+a[i].w); 
			}
		}
		cout<<dp[m]<<endl;
	}
	return 0;
}


1418: NASA的食物计划

时间限制: 1 Sec  内存限制: 128 MB
提交: 14  解决: 12
[ 提交][ 状态][ 讨论版]

题目描述

       航天飞机的体积有限,当然如果载过重的物品,燃料会浪费很多钱,每件食品都有各自的体积、质量以及所含卡路里,在告诉你体积和质量的最大值的情况下,请输出能达到的食品方案所含卡路里的最大值,当然每个食品只能使用一次.

输入

第一行两个数体积最大值(<400)和质量最大值(<400)

第二行 一个数 食品总数N(<50).

第三行-第3+N行

每行三个数 体积(<400) 质量(<400) 所含卡路里(<500)

输出

一个数 所能达到的最大卡路里(int范围内)

样例输入

320 350;4;160 40 120;80 110 240;220 70 310;40 400 22

样例输出

550

提示

#include<iostream>
#include<string.h>
using namespace std;
int dp[400][400];
struct food{
	int vi,mi,kl;
}a[405];
int main()
{
	int v,m,n;
	cin>>v>>m>>n;
	for(int i=1;i<=n;i++)
	cin>>a[i].vi>>a[i].mi>>a[i].kl;
	memset(dp,0,sizeof(dp));
	for(int i=1;i<=n;i++)
	{
		for(int j=v;j>=a[i].vi;j--)
		for(int k=m;k>=a[i].mi;k--)
		dp[j][k]=max(dp[j][k],dp[j-a[i].vi][k-a[i].mi]+a[i].kl);
    }
	cout<<dp[v][m]<<endl; 
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值