• [bzoj 2017] [Usaco2009 Nov]硬币游戏


      一个多月没更博客了。。(期间明白了自己有多傻逼。

      这种问题大概就倒着做...

      f[i][j]:表示考虑剩下的硬币i..n,且之前的人取了j个时,先手最多拿到的钱数。aft[i]:表示硬币i..n的总钱数。

      f[i][j]=aft[i]-min{ f[k][k-i] },(i<k<=min(n,i+2*j))

      k随着j的增加而增加。不同的j只是k的范围不同而已。所以记录一波最小值就可以了。

      时间复杂度O(n²)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=2023;
     7 int f[maxn][maxn];
     8 int aft[maxn],a[maxn];
     9 int i,j,k,n,m;
    10  
    11 int ra;char rx;
    12 inline int read(){
    13     rx=getchar(),ra=0;
    14     while((rx<'0'||rx>'9'))rx=getchar();
    15     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    16 }
    17 inline int min(int a,int b){return a<b?a:b;}
    18 int main(){
    19     n=read();
    20     for(i=1;i<=n;i++)a[i]=read();
    21     for(i=n;i;i--)aft[i]=aft[i+1]+a[i];
    22     for(i=n;i;i--)for(j=(n-i+2)>>1;j<=n;j++)f[i][j]=aft[i];int mn;
    23     for(i=n-1;i;i--){
    24         mn=1e9,k=i;
    25         for(j=1;j<=i;j++){
    26             if(k<=n)k++,mn=min(mn,f[k][k-i]);
    27             if(k<=n)k++,mn=min(mn,f[k][k-i]);
    28             f[i][j]=aft[i]-mn;
    29             if(k>n)break;
    30         }
    31         for(j++;j<=i;j++)f[i][j]=aft[i]-mn;
    32     }
    33     printf("%d
    ",f[1][1]);
    34 }
    View Code
  • 相关阅读:
    写入和读取本地文件。
    通过ADG技术迁移单实例到rac集群上
    更改整个目录文件的所有权限
    oracle12c安装过程netca报错failed to core dump
    oracle通过闪回查询表的更改记录
    oracle表空间使用率查询sql
    SQL执行慢的原因分析
    存储过程+定时job
    oracle goldengate搭建配置
    oracle11G Windows冷备恢复
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5596236.html
Copyright © 2020-2023  润新知