码迷,mamicode.com
首页 > 其他好文 > 详细

【题解】[USACO03FALL]Cow Exhibition G

时间:2020-10-16 10:52:39      阅读:19      评论:0      收藏:0      [点我收藏+]

标签:倒序   更新   href   顺序   names   math   set   ems   span   

题目戳我

\(\text{Solution:}\)

考虑\(dp,\)\(dp[i][j]\)表示前\(i\)个物品智商为\(j\)的情商最大值。

先考虑负数情况,可以整体挪动一个最大值,更改状态为前\(i\)个物品智商为\(j+Mx\)的情商最大值。

那么有显然\(dp\)方程:\(dp[i][j]=\max\left\{dp[i-1][j],dp[i-1][j-iq[i]]+eq[i]\right\}\)

时间复杂度为\(O(n*Mx)\)不被接受。

考虑更改状态:\(dp[j]\)表示智商为\(j+Mx\)的情商最大值。

\(dp[j]=\max\left\{dp[j-iq[i]]+eq[i]\right\}\)

考虑转移顺序:当\(iq\in Z^*\)时,一定从小的\(j\)转移到大的\(j\),故需要倒序枚举\(j,\)而当\(iq\)为负数时,为了保证一定从上一层状态转移而来,需要正序枚举\(j\).

最后的答案就是\(\max\left\{dp[j]+j-Mx\right\}\)

#include<bits/stdc++.h>
using namespace std;
const int MAXN=500;
int MR=4e5;
int eq[MAXN],iq[MAXN],n,dp[800001];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d%d",&iq[i],&eq[i]);
	}
	memset(dp,-0x3f,sizeof(dp));
	dp[MR]=0;
	MR<<=1;
	//dp[i]表示智商为i+400000的情商最大值 
	for(int i=1;i<=n;++i){
		if(iq[i]>=0){
			for(int j=MR;j>=iq[i];--j)
				dp[j]=max(dp[j],dp[j-iq[i]]+eq[i]);
			//若iq为正数,则转移会从小的转移到大的,所以顺序逆序 
		}
		else{
			for(int j=0;j<=MR+iq[i];++j)
				dp[j]=max(dp[j],dp[j-iq[i]]+eq[i]);
			//若iq为负数,则转移会从大的转移到小的,所以先利用上一层的状态来更新这一层状态
			//故顺序为逆序 
		}
	}
	int ans=0;
	for(int i=400000;i<=MR;++i){
		if(dp[i]>=0)ans=max(ans,dp[i]+i-400000);
	}
	printf("%d\n",ans);
	return 0;
} 

【题解】[USACO03FALL]Cow Exhibition G

标签:倒序   更新   href   顺序   names   math   set   ems   span   

原文地址:https://www.cnblogs.com/h-lka/p/13821813.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!