zoukankan      html  css  js  c++  java
  • [BZOJ5046]分糖果游戏

    题目大意:
      有a,b两个人分糖,每个人都有一个能量值。
      每个人每一轮可以选择进行两种操作:
        1.取走最左边的糖果,补充相应的能量值并获取相应的美味度。
        2.跳过这一轮,能量值-1.
      问在每个人都采取最优决策的情况下,每个人能获得最多的美味度是多少?

    思路:
      动态规划。
      f[i][j]表示吃第i~n的糖,并获得j的美味度,两人能量值之差最小是多少。
      如果轮到的人选择吃,那么f[i][j]=-f[i+1][suf[i]-j+1]-r[i]+1;
      如果不吃,那么f[i][j]=max(f[i+1][j]+r[i]+1,1)。
      不吃的时候要满足能量值之差>=1,因为对方同样可以通过不吃补回来。
      最后的答案k为满足f[0][k]<=a-b的最大值,糖果最后一定能吃完,所以只要减一下就得到了两个答案。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<algorithm>
     4 typedef long long int64;
     5 inline int getint() {
     6     register char ch;
     7     while(!isdigit(ch=getchar()));
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int64 inf=0x4000000000000000ll;
    13 const int N=151;
    14 int r[N],s[N],suf[N];
    15 int64 f[2][N];
    16 int main() {
    17     const int n=getint(),a=getint(),b=getint();
    18     for(register int i=0;i<n;i++) {
    19         r[i]=getint(),s[i]=getint();
    20     }
    21     for(register int i=n-1;~i;i--) {
    22         suf[i]=suf[i+1]+s[i];
    23     }
    24     for(register int i=0;i<=s[n-1];i++) {
    25         f[!(n&1)][i]=-inf;
    26     }
    27     for(register int i=s[n-1]+1;i<=suf[0];i++) {
    28         f[!(n&1)][i]=inf;
    29     }
    30     for(register int i=n-2;~i;i--) {
    31         for(register int j=suf[i];~j;j--) {
    32             if(s[i]>=j) {
    33                 f[i&1][j]=-inf;
    34                 while(j--) f[i&1][j]=-inf;
    35                 break;
    36             }
    37             f[i&1][j]=-f[!(i&1)][suf[i]-j+1]-r[i]+1;
    38             if(j<=suf[i+1]) {
    39                 f[i&1][j]=std::min(f[i&1][j],std::max(1ll,f[!(i&1)][j]+r[i]+1));
    40             }
    41         }
    42     }
    43     for(register int i=suf[0];~i;i--) {
    44         if(f[0][i]<=a-b) {
    45             printf("%d %d
    ",i,suf[0]-i);
    46             return 0;
    47         }
    48     }
    49 }
  • 相关阅读:
    Ubuntu 16 安装ElasticSearch
    二叉树
    归并排序
    快速排序
    Git、Github使用
    445. 两数相加 II
    141. 环形链表
    92. 反转链表 II
    19. 删除链表的倒数第N个节点
    2. 两数相加
  • 原文地址:https://www.cnblogs.com/skylee03/p/7810232.html
Copyright © 2011-2022 走看看