Codeforces Round #658 (Div. 2) D. Unmerge (思維,01揹包)
阿新 • • 發佈:2020-07-24
-
題意:有兩個陣列\(a\)和\(b\),每次比較它們最左端的元素,取小的加入新的陣列\(c\),若\(a\)或\(b\)其中一個為空,則將另一個全部加入\(c\),現在給你一個長度為\(2n\)的陣列\(c\),問是否能有兩個長度為\(n\)的陣列\(a\)和\(b\)構成.
-
題解:我們從左向右看\(c\),記一個最大值\(mx\),觀察樣例不難發現,跟隨在\(mx\)後面比\(mx\)小的元素,它們一定來自同一個陣列,比如第三個樣例:
3 2 6 1 5 7 8 4
\(3,2\)一定來自同一個陣列,\(6,1,5\)一定來自同一個陣列,\(7\)就一個元素,\(8,4\)一定來自同一個陣列,所以我們將它們分段,\((3,2)\)
-
程式碼:
int t; int n; int a[N]; vector<int> v; int dp[N]; int main() { scanf("%d",&t); while(t--){ scanf("%d",&n); me(dp,0,sizeof(dp)); v.clear(); for(int i=1;i<=2*n;++i){ scanf("%d",&a[i]); } int mx=a[1]; int pos=1; for(int i=2;i<=2*n;++i){ if(a[i]>mx){ v.pb(i-pos); mx=a[i]; pos=i; } } v.pb(2*n+1-pos); for(int i=0;i<v.size();++i){ for(int j=n;j>=v[i];--j){ dp[j]=max(dp[j],dp[j-v[i]]+v[i]); } } if(dp[n]==n) puts("YES"); else puts("NO"); } return 0; }