• [atAGC051B]Three Coins


    记$p_{i}$表示该位置是否有硬币

    称使得$p_{i,i+1,i+2}$都变为1的操为对$i$的添加操作,使得$p_{i,i+1,i+2}$都变为0的操作为对$i$的删除操作

    考虑一个简单的操作:若$p_{i}=1$,且$p_{i+1}=p_{i+2}=p_{i+3}=0$,可以通过执行对$i+1$的添加操作、对$i$的删除操作,使得$p_{i}$"移动"到$p_{i+3}$,我们将这个称之为对$i$的移动操作

    接下来,我们证明一个$p_{i}$能通过添加和删除操作得到,当且仅当其能通过添加和移动操作得到:

    由于移动操作是由添加和删除操作组合得到的,因此充分性满足

    称$p_{i}=1$的来源为最后一次影响到$i$(由于最终$p_{i}=1$,必然是使其变为1)的操作位置,注意到对于来源相同的两个$p_{i}=p_{j}=1$,对其操作的时间也必然相同

    考虑当执行对$i$删除操作时,对$p_{i},p_{i+1},p_{i+2}$的1的来源分类讨论,分为三种情况:

    1.通过对$i$的添加操作得到,不妨将对$i$的删除操作提前到该次操作,显然无意义;

    2.通过对$i-2$和$i+1$的添加操作,这也就是对$i$的移动操作;

    3.通过对$i-1$和$i+2$的添加操作,这也就是对$i$和$i+1$的移动操作,等价于先对$i+1$、再对$i$的移动操作

    由此,即证明删除操作都可以用添加和移动操作代替

    接下来,考虑移动操作不会经过别的1,因此不会改变1的相对顺序,由此可以发现合法当且仅当:

    选择第一次操作的3个1(模3不同余),将序列分为4部分(通过移动位置会发生改变),由于其他的1不会移动经过这3个1,要求每一个内部都是合法的

    用$f_{i,j}$表示仅考虑区间$[i,j]$的最大值,若$i$或$j$中有一个未被选择,则$f_{i,j}=max(f_{i+1,j},f_{i,j-1})$,否则分为两种情况:

    1.左右端点是同一个,那么枚举中间的点转移即可(嵌套关系)

    2.左右端点不是同一个,那么枚举两个的划分即可(并列关系)

    时间复杂度为$o(n^{3})$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 505
     4 int n,a[N],f[N][N];
     5 int main(){
     6     scanf("%d",&n);
     7     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
     8     for(int i=n;i;i--)
     9         for(int j=i+1;j<=n;j++){
    10             f[i][j]=max(f[i+1][j],f[i][j-1]);
    11             for(int k=i;k<j;k++)f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]);
    12             for(int k=i+1;k<j;k+=3)
    13                 if ((j-k)%3==1)f[i][j]=max(f[i][j],f[i+1][k-1]+f[k+1][j-1]+a[i]+a[j]+a[k]);
    14         }
    15     printf("%d",f[1][n]);
    16 }
    View Code
  • 相关阅读:
    C# FileStream 文件复制
    DataSnap Server 客户端调用 异常
    抛出异常 exception
    RAD Tokyo 10.2.2
    delphi ios info.plist
    sql 日期格式
    sql server 2014登录账号
    sql server导入excel数据
    dev16 cxgrid 在DLL里报0地址错
    sql server 查看所有表记录数
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14327363.html
Copyright © 2020-2023  润新知