Hdu 6049 --- Sdjpx Is Happy (interval DP + enumeration), hdu6049 --- sdjpx
Question Link
Problem DescriptionSdjpx 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 finds 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 when 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 maximum number of K?
Notice: every soldier has a distinct number from 1 ~ N. There are no more than 10 cases in the input.
InputFirst line is the number of instances.
For every case:
Next line is n.
Next line is the number for the n soildiers.
OutputThe maximum number of K.
Every case a line.
Sample Input251 5 4 3 254 5 1 2 3
Sample Output42. Question 1 ~ N is now required to change it into a monotonic ascending sequence through the following three actions: 1. Divide the sequence into K segments. 2. Sort the numbers in any segment to make it an ascending sequence (you can operate on multiple segments) 3. You can switch the positions of the two segments. You can only exchange the largest K value at one time? Ideas: define f [I] [j] to indicate the number of valid segments that can be divided into the intervals from I to j (valid segments indicate that the numbers in this interval are sorted in a continuous sequence, f [I] [j] indicates that after the segments are sorted in order, the segments and segments are also consecutive, such as segments 312 and 465,123 456 ), all f [I] [j] can be obtained through the interval DP, and the maximum and minimum values of each interval mx [] [], mn [] [], then enumerate all subintervals. For each subinterval [I, j], if f [I] [j]> 0, it indicates that I is consecutive after j is sorted, otherwise, enumeration is used to calculate the next interval. When f [I] [j]> 0, k = mx [I] [j], the interval [I, j] should be exchanged with the [t, k] interval, t is not sure yet. Therefore, to enumerate t (j <t <= k), you must: f [1] [I-1]> 0 & mn [1] [I-1] = 1 or I = 1, mn [t] [k] = I, f [k + 1] [n]> 0 & mx [k + 1] [n] = n or k = n, ans = max (ans, f [1] [I-1] + 1 + f [j + 1] [T-1] + 1 + f [k + 1] [n]).
The Code is as follows:
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;const int N=3e3+5;int f[N][N];int mx[N][N],mn[N][N],R[N];int main(){ ///cout << "Hello world!" << endl; int T; cin>>T; while(T--) { int n; scanf("%d",&n); memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) { scanf("%d",&mx[i][i]); mn[i][i]=mx[i][i]; f[i][i]=1; R[i]=i; } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { mx[i][j]=max(mx[i][j-1],mx[j][j]); mn[i][j]=min(mn[i][j-1],mn[j][j]); } } for(int i=2;i<=n;i++) { for(int j=1;j+i-1<=n;j++) { int k=j+i-1; if(mx[j][k]-mn[j][k]+1!=i) f[j][k]=0; else { if(mn[j][k]!=mn[j][R[j]]) f[j][k]=1; else f[j][k]=f[j][R[j]]+f[R[j]+1][k]; R[j]=k; } } } int ans=f[1][n]; for(int i=1;i<=n;i++) { for(int j=i;j<=n;j++) { if(!f[i][j]) continue; if(i==1 || (f[1][i-1]&&mn[1][i-1]==1)) { int k=mx[i][j]; if(k==n || (f[k+1][n]&&mx[k+1][n]==n)) { for(int t=j+1;t<=k;t++) { if(f[t][k]&&mn[t][k]==i) ans=max(ans,f[1][i-1]+1+f[j+1][t-1]+1+f[k+1][n]); } } } } } printf("%d\n",ans); } return 0;}