HDU 6049 Sdjpx Is Happy(dp)
2017-08-06 15:01
281 查看
Description
给出一个1~n的排列,要其将其分成k段,每段内部变成升序,且可以交换两段的值,问使得该排列变成1~n的k的最大值
Input
第一行一整数T表示用例组数,每组用例首先输入一整数n表示序列长度,之后一个1~n的排列a[i]~a
(1<=n<=3000)
Output
对于每组用例,输出使得a[1]~a
可以变成1~n的k的最大值
Sample Input
2
5
1 5 4 3 2
5
4 5 1 2 3
Sample Output
4
2
Solution
num[i][j]表示区间[i,j]在不进行段之间的交换的情况下可以分成的最多段数,一个区间[i,j]可以被分成一段当且仅当mx[i][j]-mn[i][j]=j-i,其中mx[i][j]和mn[i][j]表示该区间的最大值和最小值,O(n^2)预处理出mx和mn,对于num[i][j],如果num[i][j]想被分成多段,那么mn[i][j]必须在第一段内,且j-i=mx[i][i]-mn[i][j],num也可以在O(n^2)预处理,之后枚举要交换的第一段,假设为[i,j],首先[i,j]是连续的,而且要么i是1,要么[1,i-1]排完序后是1~i-1,令k=mx[i][j],那么要交换的第二段的右端点必然是k,且要么k是n,要么[k+1,n]排完序后是k+1~n,这些条件均满足后枚举要交换的第二段的左端点l,如果[l,k]连续且mn[l][k]=i则说明这两个区间可交换,分成的段数为num[1][i-1]+1+num[j+1][l-1]+1+num[k+1]
,维护一个最大值即为答案,由于条件限制,可以交换的段不超过n^2个
Code
给出一个1~n的排列,要其将其分成k段,每段内部变成升序,且可以交换两段的值,问使得该排列变成1~n的k的最大值
Input
第一行一整数T表示用例组数,每组用例首先输入一整数n表示序列长度,之后一个1~n的排列a[i]~a
(1<=n<=3000)
Output
对于每组用例,输出使得a[1]~a
可以变成1~n的k的最大值
Sample Input
2
5
1 5 4 3 2
5
4 5 1 2 3
Sample Output
4
2
Solution
num[i][j]表示区间[i,j]在不进行段之间的交换的情况下可以分成的最多段数,一个区间[i,j]可以被分成一段当且仅当mx[i][j]-mn[i][j]=j-i,其中mx[i][j]和mn[i][j]表示该区间的最大值和最小值,O(n^2)预处理出mx和mn,对于num[i][j],如果num[i][j]想被分成多段,那么mn[i][j]必须在第一段内,且j-i=mx[i][i]-mn[i][j],num也可以在O(n^2)预处理,之后枚举要交换的第一段,假设为[i,j],首先[i,j]是连续的,而且要么i是1,要么[1,i-1]排完序后是1~i-1,令k=mx[i][j],那么要交换的第二段的右端点必然是k,且要么k是n,要么[k+1,n]排完序后是k+1~n,这些条件均满足后枚举要交换的第二段的左端点l,如果[l,k]连续且mn[l][k]=i则说明这两个区间可交换,分成的段数为num[1][i-1]+1+num[j+1][l-1]+1+num[k+1]
,维护一个最大值即为答案,由于条件限制,可以交换的段不超过n^2个
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; typedef long long ll; typedef pair<int,int>P; const int maxn=3005; int T,n,a[maxn],num[maxn][maxn],mx[maxn][maxn],mn[maxn][maxn]; int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++) { mx[i][i]=mn[i][i]=a[i]; for(int j=i+1;j<=n;j++) mx[i][j]=max(mx[i][j-1],a[j]),mn[i][j]=min(mn[i][j-1],a[j]); } for(int i=1;i<=n;i++) { int res=1; num[i][i]=1; for(int j=i+1;j<=n;j++) { if(mn[i][j]!=mn[i][j-1])res=0; if(mx[i][j]-mn[i][j]==j-i)num[i][j]=++res; } } int ans=max(1,num[1] ); for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) if(num[i][j]&&(i==1||mn[1][i-1]==1&&mx[1][i-1]==i-1)) { int k=mx[i][j]; if(k==n||mn[k+1] ==k+1&&mx[k+1] ==n) { for(int l=k;l>j;l--) if(num[l][k]&&mn[l][k]==i) ans=max(ans,num[1][i-1]+num[j+1][l-1]+num[k+1] +2); } } printf("%d\n",ans); } return 0; }
相关文章推荐
- 2017多校第二场 HDU 6049 Sdjpx Is Happy 区间DP,复杂度优化
- hdu 6049 Sdjpx Is Happy(区间DP+暴力枚举)
- HDU 6049 Sdjpx Is Happy 贪心 区间DP 从简单的情况着手思考
- HDU 6049 Sdjpx Is Happy 区间dp+发现性质
- HDU 6049 17多校2 Sdjpx Is Happy(思维题difficult)
- Hdu-6049 Sdjpx Is Happy(贪心)
- hdu 6049 Sdjpx Is Happy
- Sdjpx Is Happy HDU - 6049 多校2
- HDU6049 Sdjpx Is Happy
- HDU6049 Sdjpx Is Happy 枚举+ST表
- HDU 5119 Happy Matt Friends(DP || 高斯消元)
- HDU 5119 Happy Matt Friends(DP)
- hdu 5119 Happy Matt Friends (dp)
- HDU 2262 Where is the canteen 概率DP 高斯消元
- HDU 5119 Happy Matt Friends (DP)2014ICPC 北京站现场赛
- hdu 5119 Happy Matt Friends【dp】
- HDU 5119 Happy Matt Friends(dp)
- HDU 5119 Happy Matt Friends (14北京 类背包dp)
- HDU 5119 Happy Matt Friends(简单二维dp)
- HDU 6030 Happy Necklace (DP)