Juice Extractor dp

题意:

水果忍者游戏,给出N个水果的出现时间和消失时间。

每次切可以清除该时刻中屏幕上的所有水果,只有combo>=3的时候才得分,得分为combo的值。

题解:

可以把每个水果看成是一段时间区间。

然后把这些区间按照出现时间为第一关键字,消失时间为第二关键字排序。

我们定义dp方程dp[i]表示最后一刀切掉第i个水果,所获得的最大积分。

那么,最优的方案肯定是在第i个水果出现时间进行切。

这样的话,转移方程

dp[i] = max(dp[i],dp[j-1]+sum);

其中sum表示j到i之间所有结束时间>=第i个水果出现时间的水果数量。

但是注意!

这个题目有一个限制,就是说每次切必定将所有的水果都切完。

也就时候如果j-1水果的出现时间=第j个水果的出现时间的话,那么是不能进行转移的,因为切第j-1个水果的时候必然把第j个水果切掉,不会留下。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
bool cmp(P p1,P p2){
	if(p1.first == p2.first) return p1.second < p2.second;
	return p1.first < p2.first;
} 
const int maxn = 1005;
P ps[maxn];
int dp[maxn];
int n;
int main(){
	int T,cas=0;
	cin>>T;
	ps[0].first = ps[0].second = -1;
	while(T--){
		memset(dp,0,sizeof(dp));
		scanf("%d",&n);
		for(int i = 1;i <= n;++i){
			int a,b;
			scanf("%d %d",&a,&b);
			ps[i] = make_pair(a,b);
		}	
		sort(ps+1,ps+1+n,cmp);
		int ans = 0;
		if(n >= 3){
			for(int i = 3;i <= n;++i){
				int tim = ps[i].first;
				int sm = 0;
				for(int j = i;j >= 1;--j){
					if(ps[j].second >= tim) sm++;
					if(ps[j-1].first != ps[j].first)
						dp[i] = max(dp[i],dp[j-1] + (sm >= 3?sm:0));
				}
				ans = max(ans,dp[i]);
			}
		}
		printf("Case #%d: %d\n",++cas,ans);
	}
	
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值