Codeforce984D-XOR-pyramid-找规律DP

(有任何问题欢迎留言或私聊

(这题和异或和半毛钱关系都没有,也别被题面吓走了)

题目:

Codeforce984D-XOR-pyramid-找规律DP_第1张图片

题意:

 给你一段长度为 n n 序列,有 q q 次询问;每次询问区间 [L,R] [ L , R ] 内最大的 f(x) f ( x ) 是多少?

f(x) f ( x ) 的含义: F(x) F ( x ) 表示 x x 个数在规定运算下的值;
x=1 x = 1 时, F(1)=a[1] F ( 1 ) = a [ 1 ] ; f(1)表示只有一个数,此时 f(x) f ( x ) 就等于那个值;
x>1 x > 1 时, F(x)=F(b[1] F ( x ) = F ( b [ 1 ] ^ b[2],b[2] b [ 2 ] , b [ 2 ] ^ b[3]...b[x1] b [ 3 ] . . . b [ x − 1 ] ^ b[x]); b [ x ] ) ; 表示 x x 个数的f值;

题目给了组解释:

F(1,2,4,8)=F(12,24,48)=F(3,6,12)=F(36,612)=F(5,10)=F(510)=F(15)=15 F ( 1 , 2 , 4 , 8 ) = F ( 1 ⊕ 2 , 2 ⊕ 4 , 4 ⊕ 8 ) = F ( 3 , 6 , 12 ) = F ( 3 ⊕ 6 , 6 ⊕ 12 ) = F ( 5 , 10 ) = F ( 5 ⊕ 10 ) = F ( 15 ) = 15


画个图理解一下:
Codeforce984D-XOR-pyramid-找规律DP_第2张图片
 此区间有5个数,用F[1][5]表示,从图中最后一步可以得出规律:
   F[1][5]=F[1][4] F [ 1 ] [ 5 ] = F [ 1 ] [ 4 ] ^ F[2][5] F [ 2 ] [ 5 ]

也就是: F[i][j]=F[i][j1] F [ i ] [ j ] = F [ i ] [ j − 1 ] ^ F[i+1][j] F [ i + 1 ] [ j ]
到这里题目就解决一半了,剩下的就是用一个dp数组维护i到j的最大F值;

状态转移方程:

F[i][j]=F[i][j1] F [ i ] [ j ] = F [ i ] [ j − 1 ] ^ F[i+1][j]; F [ i + 1 ] [ j ] ;
状态转移方程:
dp[i][j]=max(F[i][j],dp[i][j1],dp[i+1][j]); d p [ i ] [ j ] = m a x ( F [ i ] [ j ] , d p [ i ] [ j − 1 ] , d p [ i + 1 ] [ j ] ) ;
初始化:
dp[i][i]=F[i][i]=ar[i]; d p [ i ] [ i ] = F [ i ] [ i ] = a r [ i ] ;

AC代码:

#include
using namespace std;
typedef long long LL;
const int N = 5000+7;
int n,q;
int ar[N];
int dp[N][N],f[N][N];
/*
f[i][j]=f[i][j-1]^f[i+1][j];
dp[i][j]=max(f[i][j],dp[i+1][j],dp[i][j-1]);
*/
int main(){
    while(~scanf("%d",&n)){
        memset(dp,0,sizeof(dp));
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;++i){
            scanf("%d",&ar[i]);//初始化
            f[i][i]=dp[i][i]=ar[i];
        }
        for(int j=2;j<=n;++j){
            for(int i=j-1;i>=1;--i){
                f[i][j]=f[i+1][j]^f[i][j-1];//计算F值
                dp[i][j]=max(f[i][j],max(dp[i][j-1],dp[i+1][j]));//维护区间最大值
            }
        }
        scanf("%d",&q);
        while(q--){
            int a,b;
            scanf("%d%d",&a,&b);
            printf("%d\n",dp[a][b]);
        }
    }
    return 0;
}

你可能感兴趣的:(基础DP/背包DP)