HDU 4701 Game 递推+博弈

来源:互联网 发布:图像特征检测算法 编辑:程序博客网 时间:2024/05/18 08:05

点击打开链接

题意: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");elseputs("BOB");}return 0;}