51nod 1370 排列与操作
来源:互联网 发布:淘宝的竖向分类怎么弄 编辑:程序博客网 时间:2024/05/22 15:56
1370 排列与操作
题目来源: TopCoder
基准时间限制:2 秒 空间限制:131072 KB 分值: 320 难度:7级算法题
收藏
关注
给定N长排列P,其中排列指数集{1,2,3...N}组成的一个序列,序列中每个元素恰好出现一次。初始时这个排列是给出的。之后你可以进行不超过K次操作(也就是说你可以操作0次,1次..K次),每次操作如下:
1)选择一个连续的非空的子区间[L,R],其对应元素为{P[L],P[L+1],..,P[R]};
2)设这个区间元素最大值为MAX,测将这个区间的所有元素都重新赋值为MAX。
问在K次以内的操作中,你一共能构造出多少种不同的序列出来,输出这个结果 modulo1,000,000,007后的结果。
注意:两个序列A,B不同是指存在元素位置下标 i,满足A[i]!=B[i].
提示:样例中第2个小数据可以构造的4组结果包括:(3, 1, 2),(3, 2, 2),(3, 3, 2),(3, 3, 3).
1)选择一个连续的非空的子区间[L,R],其对应元素为{P[L],P[L+1],..,P[R]};
2)设这个区间元素最大值为MAX,测将这个区间的所有元素都重新赋值为MAX。
问在K次以内的操作中,你一共能构造出多少种不同的序列出来,输出这个结果 modulo1,000,000,007后的结果。
注意:两个序列A,B不同是指存在元素位置下标 i,满足A[i]!=B[i].
提示:样例中第2个小数据可以构造的4组结果包括:(3, 1, 2),(3, 2, 2),(3, 3, 2),(3, 3, 3).
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=3。每组测试数据有相同的结构构成。每组数据的第一行包含两个整数N,K,其中1<=N<=200,0<=K<=200。接下来N行每行一个整数Pi,表示排列P中第i个元素,保证1~N各出现一次。
Output
每组数据一行输出,即能构造的不同序列个数mod 10^9+7后的结果。
Input示例
32 1123 23124 24321
Output示例
2413
孔炤 (题目提供者)
C++的运行时限为:2000 ms ,空间限制为:131072 KB 示例及语言说明请按这里
【分析】
DP
dp[i][j][k]表示前i个数字,当前序列位置为j,共操作k次得到的序列方案数
需要前缀和优化
【代码】
//51nod1370 排列与操作 #include<bits/stdc++.h>#define ll long long#define fo(i,j,k) for(i=j;i<=k;i++)using namespace std;const int mod=1e9+7;const int mxn=205;int T,n,m;int dp[mxn][mxn][mxn];int p[mxn],pre[mxn],nxt[mxn],s[mxn][mxn];inline int solve(){int i,j,k,x;scanf("%d%d",&n,&m);memset(dp,0,sizeof dp);fo(i,1,n) scanf("%d",&p[i]);dp[0][0][0]=1;p[0]=p[n+1]=n+1;fo(i,1,n){j=i;while(p[j-1]<p[i]) j--;pre[i]=j;j=i;while(p[j+1]<p[i]) j++;nxt[i]=j;}fo(i,1,n){memset(s,0,sizeof s);fo(k,0,min(i,m)) fo(j,0,nxt[i]) s[k][j+1]=(s[k][j]+dp[i-1][j][k])%mod;fo(j,pre[i],nxt[i]){ fo(k,1,min(i,m)) { if(j!=i) dp[i][j][k]=(dp[i][j][k]+s[k-1][j]-s[k-1][pre[i]-1])%mod; else dp[i][j][k]=(dp[i][j][k]+s[k-1][j-1]-s[k-1][pre[i]-1])%mod;// if(j!=i) fo(x,pre[i]-1,j-1)//dp[i][j][k]=(dp[i][j][k]+dp[i-1][x][k-1])%mod;// else fo(x,pre[i]-1,j-2)// dp[i][j][k]=(dp[i][j][k]+dp[i-1][x][k-1])%mod; }}fo(k,0,min(i,m)) dp[i][i][k]=(dp[i][i][k]+dp[i-1][i-1][k])%mod;fo(j,0,n) fo(k,0,min(i-1,m)) dp[i][j][k]=(dp[i][j][k]+dp[i-1][j][k])%mod;}int ans=0;fo(i,0,m) ans=(ans+dp[n][n][i])%mod;return (ans+mod)%mod;}int main(){int i,j;scanf("%d",&T);while(T--) printf("%d\n",solve());return 0;}/*12 11 2*/
阅读全文
0 0
- 51nod 1370 排列与操作
- 51nod 1370 排列与操作
- 51nod 1260 排列与二叉树
- 51nod 1250 排列与交换
- 51nod 1250 排列与交换
- 51nod 排列与交换 序列dp
- 51nod 全排列
- [51nod1370] 排列与操作
- 51nod1370 排列与操作
- 51nod 1250 排列与交换 动态规划
- 全排列【51nod】【全排列】
- 1384全排列【51NOD】
- 51NOD 1384 全排列
- 51Nod 1454 升排列
- 51NOD 1020 逆序排列
- 51nod 1384 全排列
- 51Nod--1384全排列
- 51NOD 1384 全排列
- 支付宝服务窗的简单开发体会
- PostgreSQL 9种索引的原理和应用场景
- 扒一扒那些说起来简单做着难的技术需求
- Python函数-关键字参数
- 大数据学习之路-第04天-centos防火墙操作-开启防火墙&关闭防火墙
- 51nod 1370 排列与操作
- JAVA传参
- 基于spring mvc下请求的简单工作流程及其相应配置集成
- Java反射(一)----基础介绍
- qt之Q_PROPERTY
- ADSL命令定时切换
- Hyperledger fabric0.6的链码接口整理
- Spring读取properties文件加密解密
- Android Studio如何获取SHA1或MD5(百度地图API开发中用到的SHA1)