zoukankan      html  css  js  c++  java
  • P3147 [USACO16OPEN]262144

    P3147 [USACO16OPEN]262144
    一道非常有趣的游戏,不,题目。
    当数据水时,可以这样表示状态。
    f[i][j]表示合并[i,j]区间所能得到的最大值,有点floyed的小味道。
    if(f[i][k]==f[k+1][j])
    f[i][j]=max(f[i][k]+1,f[i][j]);
    不断更新答案。
    这样需要枚举左右端点和中间点,O(n^3)
    300以内的数据可以水过。
    状态的设定直接把dp拉到暴力里去了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<ctime>
     7 #include<cstring>
     8 #define inf 2147483647
     9 #define For(i,a,b) for(register int i=a;i<=b;i++)
    10 #define p(a) putchar(a)
    11 #define g() getchar()
    12 //by war
    13 //2017.10.26
    14 using namespace std;
    15 int n;
    16 int x;
    17 int f[300][300];
    18 int ans;
    19 void in(int &x)
    20 {
    21     int y=1;
    22     char c=g();x=0;
    23     while(c<'0'||c>'9')
    24     {
    25     if(c=='-')
    26     y=-1;
    27     c=g();
    28     }
    29     while(c<='9'&&c>='0')x=x*10+c-'0',c=g();
    30     x*=y;
    31 }
    32 void o(int x)
    33 {
    34     if(x<0)
    35     {
    36         p('-');
    37         x=-x;
    38     }
    39     if(x>9)o(x/10);
    40     p(x%10+'0');
    41 }
    42 int main()
    43 {
    44     in(n);
    45     For(i,1,n)
    46     {
    47         in(x);
    48         f[i][i]=x;
    49     }
    50     For(j,1,n)
    51       for(int i=j;i>=1;i--)
    52         For(k,i,j-1)
    53           if(f[i][k]==f[k+1][j])
    54           {
    55               f[i][j]=max(f[i][k]+1,f[i][j]);
    56               ans=max(ans,f[i][j]);
    57           }
    58     o(ans);
    59      return 0;
    60 }


    O.O
    优化状态:
    有点倍增的小味道。
    i表示数值,j表示区间的左端点,f[i][j]表示右端点,如果存在这样的右端点,就把ans更新为i。怎么转移呢?
    if(!f[i][j]&&f[i-1][j])
    f[i][j]=f[i-1][f[i-1][j]+1];
    画个图就明白了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<ctime>
     7 #include<cstring>
     8 #define inf 2147483647
     9 #define For(i,a,b) for(register int i=a;i<=b;i++)
    10 #define p(a) putchar(a)
    11 #define g() getchar()
    12 //by war
    13 //2017.10.26
    14 using namespace std;
    15 int n;
    16 int x;
    17 int f[65][300];//18M
    18 int ans;
    19 void in(int &x)
    20 {
    21     int y=1;
    22     char c=g();x=0;
    23     while(c<'0'||c>'9')
    24     {
    25     if(c=='-')
    26     y=-1;
    27     c=g();
    28     }
    29     while(c<='9'&&c>='0')x=x*10+c-'0',c=g();
    30     x*=y;
    31 }
    32 void o(int x)
    33 {
    34     if(x<0)
    35     {
    36         p('-');
    37         x=-x;
    38     }
    39     if(x>9)o(x/10);
    40     p(x%10+'0');
    41 }
    42 int main()
    43 {
    44     in(n);
    45     For(i,1,n)
    46     {
    47         in(x);
    48         f[x][i]=i;
    49     }
    50     For(i,1,60)
    51       For(j,1,n)
    52         if(!f[i][j]&&f[i-1][j]&&f[i-1][f[i-1][j]+1])
    53         {
    54             f[i][j]=f[i-1][f[i-1][j]+1];
    55             ans=i;
    56         }
    57     o(ans);
    58      return 0;
    59 }
  • 相关阅读:
    软件工程概论
    软件工程概论
    JAVA
    JAVA
    C#字符补位
    C#绘图双缓冲
    C#中IP地址转换为数值的方法
    C#并行编程-并发集合
    C#委托
    C#事件(event)解析
  • 原文地址:https://www.cnblogs.com/war1111/p/7732961.html
Copyright © 2011-2022 走看看