Sdjpx Is Happy
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 416 Accepted Submission(s): 170
Problem Description
Sdjpx is a powful man,he controls a big country.There are n soldiers numbered 1~n(1<=n<=3000).But there is a big problem for him.He wants soldiers sorted in increasing order.He find a way to sort,but there three rules to obey.
1.He can divides soldiers into K disjoint non-empty subarrays.
2.He can sort a subarray many times untill a subarray is sorted in increasing order.
3.He can choose just two subarrays and change thier positions between themselves.
Consider A = [1 5 4 3 2] and P = 2. A possible soldiers into K = 4 disjoint subarrays is:A1 = [1],A2 = [5],A3 = [4],A4 = [3 2],After Sorting Each Subarray:A1 = [1],A2 = [5],A3 = [4],A4 = [2 3],After swapping A4 and A2:A1 = [1],A2 = [2 3],A3 = [4],A4 = [5].
But he wants to know for a fixed permutation ,what is the the maximum number of K?
Notice: every soldier has a distinct number from 1~n.There are no more than 10 cases in the input.
1.He can divides soldiers into K disjoint non-empty subarrays.
2.He can sort a subarray many times untill a subarray is sorted in increasing order.
3.He can choose just two subarrays and change thier positions between themselves.
Consider A = [1 5 4 3 2] and P = 2. A possible soldiers into K = 4 disjoint subarrays is:A1 = [1],A2 = [5],A3 = [4],A4 = [3 2],After Sorting Each Subarray:A1 = [1],A2 = [5],A3 = [4],A4 = [2 3],After swapping A4 and A2:A1 = [1],A2 = [2 3],A3 = [4],A4 = [5].
But he wants to know for a fixed permutation ,what is the the maximum number of K?
Notice: every soldier has a distinct number from 1~n.There are no more than 10 cases in the input.
Input
First line is the number of cases.
For every case:
Next line is n.
Next line is the number for the n soildiers.
For every case:
Next line is n.
Next line is the number for the n soildiers.
Output
the maximum number of K.
Every case a line.
Every case a line.
Sample Input
2 5 1 5 4 3 2 5 4 5 1 2 3
Sample Output
4 2HintTest1: Same as walk through in the statement. Test2: [4 5] [1 2 3] Swap the 2 blocks: [1 2 3] [4 5].
题意:给一个序列,问最多能分成多少组,组内排序后,可以交换两个组的顺序,使整个序列升序;
解:首先处理出一段区间是否合法,即最大值-最小值==区间长度,合法即为1,然后计算出一段区间最多能分成几组;
暴力枚举出两个可能交换顺序的区间,一共2种情况 (1)当前区间是第一段但是最小值不为1,找到这段区间最大值得位置,如果他的右边合法且最大值为n则
枚举左边界直到最小值为1;(2)这段区间不在第一段,但是左边界最小值为1即左边合法,按照(1)的方法找要交换的位置
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include <bits/stdc++.h>
using namespace std;
const int N = 3000+10;
typedef long long LL;
const LL mod = 1e9+7;
int dp[N][N], save[N],mn[N][N],mx[N][N], a[N];
int n;
void init()
{
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++)
dp[i][i]=1,mn[i][i]=mx[i][i]=a[i],save[i]=i;
for(int i=1; i<=n; i++)
{
for(int j=i+1; j<=n; j++)
{
mn[i][j]=min(mn[i][j-1],a[j]);
mx[i][j]=max(mx[i][j-1],a[j]);
}
}
for(int l=2; l<=n; l++)
{
for(int i=1; i+l-1<=n; i++)
{
int j=i+l-1;
if(mx[i][j]-mn[i][j]+1!=l) dp[i][j]=0;
else
{
int k=save[i];
if(mn[i][k]>mn[i][j]) dp[i][j]=1;
else dp[i][j]=dp[i][k]+dp[k+1][j];
save[i]=j;
}
}
}
}
int solve()
{
int ans=max(1,dp[1][n]);
for(int i=1; i<=n; i++)
{
for(int j=i; j<=n; j++)
{
if(dp[i][j]&&(i==1||(dp[1][i-1]&& mn[1][i-1]==1)))
{
int k=mx[i][j];
if(k==n||(mx[k+1][n]==n&&dp[k+1][n]))
{
for(int t=j+1;t<=k;t++)
{
if(dp[t][k]&&mn[t][k]==i)
{
ans=max(ans,dp[1][i-1]+1+dp[j+1][t-1]+1+dp[k+1][n]);
}
}
}
}
}
}
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(int i=1; i<=n; i++) scanf("%d", &a[i]);
init();
printf("%d\n",solve());
}
return 0;
}