uvalive 5760 Alice and Bob (组合游戏,dp)

本文探讨了如何使用动态规划解决堆合并问题,并通过实例展示了二维dp在处理此类问题时的应用。通过深入分析和算法实现,阐述了堆操作数与堆个数之间的关系,最终确定了是否可以将所有堆合并为一个堆的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接: http://vjudge.net/problem/viewProblem.action?id=25636

对于>1的堆,必然会被其中一人全部合并。

然后就是二维dp,dp[非1堆的操作数][1堆个数]。

#include <stdio.h>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
           
using namespace std;
#define lson o<<1
#define rson o<<1|1
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
#define INF 200000000
           
typedef long long ll;
int dp[60][50100];
int dfs(int one,int tot){
    if(dp[one][tot]>-1)return dp[one][tot];
    if(tot==1)return dp[one][tot]=dfs(one+1,0);
    if(one==0)return dp[one][tot]=tot&1;
    if(tot>0&&!dfs(one,tot-1))return dp[one][tot]=1;
    if(!dfs(one-1,tot))return dp[one][tot]=1;
    if(tot&&!dfs(one-1,tot+1))return dp[one][tot]=1;
    if(one>=2)
       if((tot&&!dfs(one-2,tot+3))||(!tot&&!dfs(one-2,tot+2)))
           return dp[one][tot]=1;
    
    return dp[one][tot]=0;
}           
int main(){
   int t,cs,n;
   scanf("%d",&t);
   memset(dp,-1,sizeof dp);
   dp[0][0]=0;
   for(cs=1;cs<=t;cs++){
      scanf("%d",&n);
      int x,one=0,tot=0;
      for(int i=0;i<n;i++){
         scanf("%d",&x);
         if(x==1)one++;
         else
            tot+=x+1;
      }
      if(tot)tot--;
      printf("Case #%d: ",cs);
      if(dfs(one,tot))printf("Alice\n");
      else printf("Bob\n");
   }
   return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值