Codeforce984D-XOR-pyramid-找规律DP

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

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

题目:

这里写图片描述

题意:

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

f(x) f ( x ) 的含义: F(x) F ( x ) 表示 x x 个数在规定运算下的值;
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


画个图理解一下:
这里写图片描述
 此区间有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<bits/stdc++.h>
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;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值