HDU 4701 Game 递推+博弈

点击打开链接

题意:n个物品,每个价值c[i],两人分别有A,B元,每次轮流购买>=1件物品,规则:购买第i(i>1)件时,i-1件必须被购买,不能购买算输
n<=1e6,c[i],A,B<=1e9
首先:如果Alice有x元就能必胜,则有y(y>x)元肯定也能获胜
则设计状态d[i] 在买第i件物品前 必胜所需要的最小价钱
sum[i] 为前i件物品之和 ,若第i件先手时有d[i]元,则对手的钱为y:A+B=y+d[i]+sum[i-1] y=A+B-d[i]-sum[i-1] 
递推d[i]: 考虑第i+1件物品是否买.
若不买第i+1件物品 则必须给对手在i+1留下必败态 A+B-d[i]-sum[i-1]<d[i+1]
买第i+1件物品(或者之后的物品) 相当于先转移到dp[i+1]的必胜态  d[i]=d[i+1]+c[i]

  

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int N=2e6+20;
const int M=650;
ll c[N],A,B,sum[N],n;
ll dp[N];
int main()
{ 
	while(cin>>n>>A>>B)
	{
		sum[0]=0;
		for(int i=1;i<=n;i++)
			scanf("%I64d",&c[i]),sum[i]=sum[i-1]+c[i];
		int len=n;
		for(int i=1;i<=n;i++)
		{
			//最多买到i-1 
			if(sum[i]>A+B)
			{
				len=i-1;
				break;	
			}	
		}
		dp[len]=c[len]; 
		for(int i=len-1;i>=1;i--)
		{
			dp[i]=dp[i+1]+c[i]; 
			ll t=A+B-sum[i-1]-dp[i+1]+1;
			dp[i]=min(dp[i],t);
		} 
		if(A>=dp[1])
			puts("ALICE");
		else
			puts("BOB");		
	}
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值