zoukankan      html  css  js  c++  java
  • bzoj3594: [Scoi2014]方伯伯的玉米田--树状数组优化DP

    题目大意:对于一个序列,可以k次选任意一个区间权值+1,求最长不下降子序列最长能为多少

    其实我根本没想到可以用DP做

    f[i][j]表示前i棵,操作j次,最长子序列长度

    p[x][y]表示操作x次后,最高玉米为y时的最长子序列长度

    那么以n棵玉米分阶段,对于每个阶段

    f[i][j]=max{p[k][l]}+1,  其中k=1 to j , l=1 to a[i]+j

    然后用树状数组维护p[][]的最大值

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 int p[505][6005],f[10005][505];
     6 int n,K,M,ans,a[10005];
     7 
     8 int solve(int x, int t){
     9     int res=0;
    10     while (x){
    11         int y=t;
    12         while (y){
    13             res=max(res,p[x][y]);
    14             y-=y&-y;
    15         }
    16         x-=x&-x;
    17     }
    18     return res;
    19 }
    20 
    21 void update(int x, int t, int c){
    22     while (x<=K){
    23         int y=t;
    24         while (y<=M){
    25             p[x][y]=max(p[x][y],c);
    26             y+=y&-y;
    27         }
    28         x+=x&-x;
    29     }
    30 }
    31 
    32 int main(){
    33     scanf("%d%d", &n, &K);
    34     K++;
    35     for (int i=1; i<=n; i++){
    36         scanf("%d", &a[i]);
    37         M=max(M,a[i]);
    38     }
    39     M+=K;
    40     ans=0;
    41     for (int i=1; i<=n; i++){
    42         for (int j=1; j<=K; j++){
    43             f[i][j]=solve(j,a[i]+j)+1;  // k=1~j; l=a[i]~a[i]+j;  p[k][l]用了k次,最高是a[i]+j 最长子序列长度 
    44             ans=max(ans,f[i][j]);
    45         }
    46         for (int j=1; j<=K; j++)
    47             update(j,a[i]+j,f[i][j]);
    48     }
    49     printf("%d
    ", ans);
    50     return 0;
    51 }
  • 相关阅读:
    png 的特点
    UIImangeView的用法
    uiTextView简单的用法
    UITextField简单的用法
    UIWindow的简单实用(二)
    UIView的简单实用
    objective-C 复合(组合)
    OC
    objective-C protocol协议
    object-C NSDate
  • 原文地址:https://www.cnblogs.com/mzl0707/p/5532655.html
Copyright © 2011-2022 走看看