打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Codeforces Round #658 (Div. 2)D(01背包)

题意:给定随意俩个数组的合并规则,每次取俩个数组第一个的最小值,直至俩数组为空.。给定目标数组(1~n出现1次)问能不能2个数组合并成目标数组

分析:可以把目标数组分成若干段,要是能每段都连续给到且某些段能刚好凑成n的大小,那么问题就可以解决;

   而要达到“每段连续给到”:遍历目标数组取“连续降序段”。

   而要达到“某些段能刚好凑成n的大小”:对“连续降序段”的大小进行01背包,看dp[n]是不是恰好为n。

#include<bits/stdc++.h>using namespace std;#define pb push_back#define MP make_pairtypedef long long ll;typedef unsigned long long ull;const int mod=998244353;const int inf=0x3f3f3f3f;const ll INF=1e18;const int M=4e3+3;int dp[M],a[M],w[M];int main(){    int t;    scanf("%d",&t);    while(t--){        int n;        scanf("%d",&n);        for(int i=0;i<=n;i++)            dp[i]=0;        for(int i=1;i<=2*n;i++)            scanf("%d",&a[i]);        int maxx=a[1];        int countt=1,tot=0;        for(int i=2;i<=2*n;i++){            if(maxx>a[i])countt++;            else{                w[tot++]=countt;                countt=1;                maxx=a[i];            }        }        w[tot++]=countt;        sort(w,w+tot);        for(int i=0;i<tot;i++)            for(int j=n;j>=w[i];j--)                dp[j]=max(dp[j],dp[j-w[i]]+w[i]);        if(n==dp[n])            puts("YES");        else            puts("NO");    }    return 0;}

View Code

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
“2018宁夏邀请赛 ” 兼 “The 2019 Asia Yinchuan First Round Online Programming”
01背包 | 勇幸|Thinking
NOIP复赛复习(四)程序对拍与图论模板
[DP浅析]线性DP初步 - 2 - 单调队列优化
动态规划之背包问题(一)
算法导论16.2
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服