竞赛得分(dp)

   日期:2020-08-22     浏览:84    评论:0    
核心提示:竞赛得分题目学生在我们USACO的竞赛中的得分越多我们越高兴。我们试着设计我们的竞赛以便人们能尽可能的多得分。现在要进行一次竞赛,总时间T固定,有若干类型可选择的题目,每种类型题目可选入的数量不限,每种类型题目有一个si(解答此题所得的分数)和ti(解答此题所需的时间),现要选择若干题目,使解这些题的总时间在T以内的前提下,所得的总分最大。输入包括竞赛的时间,M(1 <= M <= 10000)和题目类型数目N(1 <= N <= 10000)。后面的每一行将包括两个整数来描

竞赛得分

题目

学生在我们USACO的竞赛中的得分越多我们越高兴。我们试着设计我们的竞赛以便人们能尽可能的多得分。现在要进行一次竞赛,总时间T固定,有若干类型可选择的题目,每种类型题目可选入的数量不限,每种类型题目有一个si(解答此题所得的分数)和ti(解答此题所需的时间),现要选择若干题目,使解这些题的总时间在T以内的前提下,所得的总分最大。
输入包括竞赛的时间,M(1 <= M <= 10000)和题目类型数目N(1 <= N <= 10000)。
后面的每一行将包括两个整数来描述一种"题型":
第一个整数说明解决这种题目能得的分数(1 <= points <= 10000),第二整数说明解决这种题目所需的时间(1 <= minutes <= 10000)。

Input

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

Output

单独的一行,在给定固定时间里得到的最大的分数。

Sample Input

300 4
100 60
250 120
120 100
35 20

Sample Output

605

Hint

【注释】从第2种类型中选两题和第4种类型中选三题

题解

这是一题完全背包问题,因为每道题可以做无限遍。
外层循环枚举n种题,内层枚举竞赛的时间,但枚举时间时不能像01背包一样从v到1,
而是从1到v。因为每次计算最大分数时都需用到前面的状态。
i为枚举的题,j为枚举的时间,f[i][j]表示当时间为j时,前i道题能达到的最大分数。
b为题目时间,a为分值,状态转移方程:(j>b[i]) , f[i][j]=max(f[i-1][j],f[i][j-b[i]]+a[i]) , 1<=i<=n, 1<=j<=v
意思是如果做题目i的分值大于不做,f[i][j]等于做题的分值,否则等于不做题即上一道题的最大分值

代码

#include<cstdio>
#include<cmath> 
#include<iostream>
#include<iomanip>
using namespace std;
int n,a[10001],s,ans,f[10001][10001],v,b[10001];
void dp(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=v;j++){
			if(j>=b[i]){
				f[i][j]=max(f[i-1][j],(f[i][j-b[i]]+a[i]));//选择最优状态
			}else{
				f[i][j]=f[i-1][j];
			}ans=max(ans,f[i][j]);//记录答案为最大分值
		}
	}
}
void in(){
	cin>>v>>n;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i],&b[i]);
	}
}
int main(){
	in();
	dp();
	cout<<ans;
}
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服