HDU6049-Sdjpx Is Happy

Sdjpx Is Happy

                                                                   Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
                                                                                             Total Submission(s): 528    Accepted Submission(s): 221


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.
 

Input
First line is the number of cases.
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.
 

Sample Input
 
   
2 5 1 5 4 3 2 5 4 5 1 2 3
 

Sample Output
 
   
4 2
Hint
Test1: Same as walk through in the statement. Test2: [4 5] [1 2 3] Swap the 2 blocks: [1 2 3] [4 5].
 

Source
2017 Multi-University Training Contest - Team 2
 

题意:给一个序列,问最多能分成多少组,组内排序后,可以交换两个组的顺序,使整个序列升序

解题思路:先预处理,mi[i][j]记录区间最小值,ma[i][j]记录区间最大值,dp[i][j]记录(i,j)段最多可以被分成几个小段, x[i]记录从i开始的上次的可行区间的右端点。然后设要交换的区间为a,b。先枚举a的左右端点并且a必须满足可行,即dp[i][j]!=0,同时必须满足,a为最左边的段或者a左边的段包括了(1,i-1)的数字。设p为a中的最大值,则如果k==n的话,那么b是最右边的段,否则b右边的段为(k+1,n),且必须包括(k+1,n)中的所有数,然后枚举b的左端点k使b合法并且mi[t][k]==i,才能保证a和b交换后整个数列从1~n递增


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;
const LL mod=1000000007;

int n,a[3009],x[3009];
int dp[3009][3009],ma[3009][3009],mi[3009][3009];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1; i<=n; i++) scanf("%d",&a[i]),dp[i][i]=1,ma[i][i]=mi[i][i]=a[i],x[i]=i;
        for(int i=2; i<=n; i++)
            for(int j=1; j+i-1<=n; j++)
            {
                ma[j][i+j-1]=max(ma[j][j+i-2],a[j+i-1]);
                mi[j][i+j-1]=min(mi[j][i+j-2],a[i+j-1]);
            }
        for(int i=2; i<=n; i++)
        {
            for(int j=1; j+i-1<=n; j++)
            {
                int k=i+j-1;
                if(ma[j][k]-mi[j][k]+1!=i) dp[j][k]=0;
                else
                {
                    if(mi[j][k]

你可能感兴趣的:(HDU,----线性dp)