cf1382D---思維+01揹包
阿新 • • 發佈:2020-08-06
題目連結:https://codeforces.com/contest/1382/problem/D
簡單題意:給定1到2*n的一個排列,問是否能由兩個長度為n的陣列歸併得到
首先注意到,原來2*n的排列中,一個數和右邊連續的所有比它小的數,是必須在一個數組裡的。這樣就可以把原2*n排列分段。比如樣例中 6 1 3|7 4 5|8 2各個段的長度就是3 3 2。如果有一些段的長度和為n,那麼把它們放到一個數組裡就可以了(然後將另外的段放到另一個數組,容易發現這樣是滿足的)。是否存在一些段長度和為n可以用01揹包判斷
#include<bits/stdc++.h> using namespace std; const int maxn=4000+10; int t,n,i,j,k,cnt,a[maxn],c[maxn],dp[maxn]; int main(){ scanf("%d",&t); while (t--){ scanf("%d",&n); for (i=1;i<=2*n;i++) scanf("%d",&a[i]); a[2*n+1]=1e9; i=1;j=2; cnt=0; while (i<=2*n){ //* 求出每段長度 while (a[j]<a[i]) j++; c[++cnt]=j-i; i=j; j=i+1; } memset(dp,0,sizeof(dp)); dp[0]=1; for (i=1;i<=cnt;i++) //01揹包 for (j=n;j>=c[i];j--) if (dp[j-c[i]]) dp[j]=1; if (dp[n]) puts("YES\n"); else puts("NO\n"); } return 0; }