zoukankan      html  css  js  c++  java
  • Codeforces 984D 题解(DP)

    题面

    传送门
    题目大意:
    给你一个计算区间f函数的公式,举例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 然后现在给你一个数列,n<=5000,然后q个询问,q<=100000,每次询问[l,r]区间内f函数的最大值是多少

    分析

    此题可用DP求解
    dp[i][j]dp[i][j]表示区间[i,j]f函数最大值
    显然初始值dp[i][i]=a[i]dp[i][i]=a[i]
    15
    5 10
    3 6 12
    1 2 4 8
    我们把题面例子中每个区间的f值写成一个金字塔形
    从下到上为1~4行
    对于每个区间[l,r],其实我们要统计的是金字塔中的一小部分的最大值
    如[1,2],即求金字塔
    3
    1 2
    的最大值,显然是3
    显然可以从下到上递推写出
    dp[i][j]=dp[i+1][j]xordp[i][j]=dp[i+1][j]xor dp[i][j1]dp[i][j−1]
    又因为要统计最大值
    dp[i][j]=max(dp[i+1][j],dp[i][j1],dp[i][j[)dp[i][j]=max(dp[i+1][j],dp[i][j−1],dp[i][j[)
    总的状态转移方程为
    dp[i][j]=max(dp[i+1][j],dp[i][j1],dp[i+1][j]xordp[i][j1])dp[i][j]=max(dp[i+1][j],dp[i][j−1],dp[i+1][j]xordp[i][j−1])
    在代码中分步实现更方便
    时间复杂度O(n2)O(n2)

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 5005
    using namespace std;
    int n,q;
    int dp[maxn][maxn];
    int l,r;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&dp[i][i]);
        for(int i=n;i>=1;i--){
            for(int j=i+1;j<=n;j++){
                dp[i][j]=dp[i][j-1]^dp[i+1][j];
            }
        }
        for(int i=n;i>=1;i--){
            for(int j=i+1;j<=n;j++){
                dp[i][j]=max(dp[i][j],max(dp[i][j-1],dp[i+1][j]));
            }
        }
        scanf("%d",&q);
        for(int i=1;i<=q;i++){
            scanf("%d %d",&l,&r);
            printf("%d
    ",dp[l][r]);
        } 
    } 
  • 相关阅读:
    [原]C++ double 小数精度控制
    C++ double 小数精度控制
    从微软小冰看微软运营手段的转型
    Windows下搭建FTP服务器
    C++ 下使用curl 获取ftp文件
    解决MSF更新证书错误
    mimikaz获取明文密码
    metasploit5配置数据库
    Cobalt Strike几种不常见的上线方式
    Powershell
  • 原文地址:https://www.cnblogs.com/birchtree/p/9858042.html
Copyright © 2011-2022 走看看