BZOJ4621 Tc605

来源:互联网 发布:ntfs for mac 10.11.6 编辑:程序博客网 时间:2024/06/11 15:05

orz wangyurzee的题解

对于第i个点,他可能不操作,这样f[k][i]+=f[k][i-1],然后若他操作,则枚举操作之后他的右端点j,设L是他能延伸到的最左的点,f[k+1][j]+=sigma l=L-1to j f[k][l](DP的时候不需要考虑操作的顺序),这个可以用前缀和处理,然后我们要把f[k+1][i]减去f[k][i-1],因为这样转移相当于没操作

#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<algorithm>#include<iomanip>#include<vector>#include<stack>#include<queue>#include<map>#include<set>#include<bitset>using namespace std;#define MAXN 510#define MAXM 1010#define ll long long#define INF 1000000000#define MOD 1000000007#define eps 1e-8int f[MAXN][MAXN];int a[MAXN];int sum[MAXN];int n,m;int main(){int i,j,k;scanf("%d%d",&n,&m);for(i=1;i<=n;i++){scanf("%d",&a[i]);}f[0][0]=1;for(i=1;i<=n;i++){int l,r;for(l=i;a[l-1]<a[i]&&l>1;l--){}for(r=i;a[r+1]<a[i]&&r<n;r++){}f[m][i]+=f[m][i-1];for(k=m-1;k>=0;k--){sum[l-1]=f[k][l-1];for(j=l;j<=r;j++){(f[k+1][j]+=sum[j-1])%=MOD;sum[j]=(sum[j-1]+f[k][j])%MOD;}(f[k][i]+=f[k][i-1])%=MOD;(f[k+1][i]+=MOD-f[k][i-1])%=MOD;}}int ans=0;for(i=0;i<=m;i++){(ans+=f[i][n])%=MOD;}printf("%d\n",ans);return 0;}/**/


0 0