• bzoj 4621 Tc605 思想+dp


    4621: Tc605

    Time Limit: 15 Sec  Memory Limit: 128 MB
    Submit: 328  Solved: 183
    [Submit][Status][Discuss]

    Description

    最初你有一个长度为 N 的数字序列 A。为了方便起见,序列 A 是一个排列。
    你可以操作最多 K 次。每一次操作你可以先选定一个 A 的一个子串,然后将这个子串的数字全部变成原来这个子串的最大值。问最终有几种可能的数字序列。答案对 1e9+7 取模。

    Input

    第一行两个数 N 和 K。第二行 N 个数,描述一个排列 A。 
    N,K<=500,
    有6组数据N>100,有梯度

    Output

    输出一个数,表示答案在模域下的值。 

    Sample Input

    3 2
    3 1 2

    Sample Output

    4

    HINT

    Source

    TC 605 Hard

    这道题的思想王聿中大神十分牛逼。

    https://www.cnblogs.com/wangyurzee7/p/5554380.html

    发现对于一个数可以操作的范围是确定的,然后

    发现最终的序列中,除了没有操作的序列,如果操作了一定是1-k之间的段数。

    f[i][j]表示分成了i段数,是1-j这些数产生的方案数,为什么i为段数,

    因为在更新的时候,比如x这个点,可以操作的范围是l--r,那么从f[i-1][l-r]中更新。

    用到了前缀和优化降低一维,变成了n^3

     1 #pragma GCC optimize(2)
     2 #pragma G++ optimize(2)
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<cstdio>
     7 #include<cstring>
     8 
     9 #define N 507
    10 #define mod 1000000007
    11 #define ll long long
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    17     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 
    21 int n,K;
    22 int a[N];
    23 int f[N][N],delta[N];
    24 
    25 int main()
    26 {
    27     f[0][0]=1;
    28     n=read(),K=read();
    29     for (int i=1;i<=n;i++)
    30         a[i]=read();
    31     for (int i=1;i<=n;i++)
    32     {
    33         int l,r;
    34         for (l=i;l>1&&a[l-1]<a[i];l--);
    35         for (r=i;r<n&&a[r+1]<a[i];r++);
    36         (f[K][i]+=f[K][i-1])%=mod;
    37         for (int k=K-1;k>=0;k--)
    38         {
    39             delta[l-1]=0;
    40             for (int j=l;j<=r;j++)delta[j]=(delta[j-1]+f[k][j-1])%mod;
    41             for (int j=l;j<=r;j++)(f[k+1][j]+=delta[j])%=mod;
    42             (f[k][i]+=f[k][i-1])%=mod;//什么都不操作
    43             (f[k+1][i]+=mod-f[k][i-1])%=mod;//自己这个已经加过了
    44         }
    45     }
    46     int ans=0;
    47     for (int i=0;i<=K;i++)
    48         (ans+=f[i][n])%=mod;
    49     printf("%d
    ",ans);
    50 }
  • 相关阅读:
    selenium自动化测试资源整理
    python获取目录下文件夹名称
    Appium-测试失败后屏幕截图的
    appium 多个设备同时执行
    七 Appium常用方法介绍
    六 APPIUM Android 定位方式
    Python运维开发基础08-文件基础
    Python运维开发基础09-函数基础
    Python运维开发基础06-语法基础
    Python运维开发基础07-文件基础
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8487395.html
Copyright © 2020-2023  润新知