一道另类的区间dp题 -- P3147 [USACO16OPEN]262144

https://www.luogu.org/problemnew/show/P3147

此题与上一题完全一样,唯一不一样的就是数据范围;

上一题是248,而这一题是262144;

普通的区间dp表示状态表示法根本存不下,

这时我们就要想另外的状态表示法;

 

#include <bits/stdc++.h>
#define read read()
#define up(i,l,r) for(int i = (l);i <=(r); i++)
using namespace std;
int read
{
    int x = 0; char ch = getchar();
    while(ch < 48 || ch > 57) ch = getchar();
    while(ch >= 48 && ch <= 57) {x = 10 * x + ch - 48; ch = getchar();}
    return x;
}
int n,f[270000][60],ans;// 262144 -> 2 ^ 18 //所以最多 40 + 18 = 58;  
//f[i][j]表示到第i个数,得到数值为j,向右合并的最右端点.(左闭右开 -> [,) ) 
int main()
{
    freopen("262144.in","r",stdin);
    n = read; up(i,1,n) f[i][(read)] = i + 1;
    up(j,2,58)
        up(i,1,n)
        {
            if(f[i][j] == 0) f[i][j] = f[f[i][j-1]][j-1];
            if(f[i][j]) ans = j;//right : 包括上面的,f[i][j] > 0时才更新 
            //else ans = j; //-> false //容易写错 
            //f[i][j]大于0是关键;
        }
    printf("%d",ans);
    return 0;
}

 

posted @ 2019-01-25 14:45  陈星卿  阅读(189)  评论(0编辑  收藏  举报