• poj 3017 Cut the Sequence(单调队列优化DP)


    Cut the Sequence



    $ solution: $

    这道题出的真的很好,奈何数据水啊!

    这道题当时看得一脸懵逼,说二分也不像二分,说贪心也不像贪心,说搜索吧这题数据范围怎么这么大?而且这题看起来也实在不好DP,当时是真的满头雾水。只能说是各个都尝试一下。最后还是选了DP来做第一步突破,因为这道题可以用最优子结构来推出最优答案,也符合常规DP套路即设 $ F[i][j] $ 表示将前面 $ i $ 个数分成 $ j $ 份,但是这一道题没有说具体的份数,而且数据范围很大,所以我们直接设 $ F[i] $ 表示前 $ i $ 个数的最优答案。这个的转移方程还是比较好想的:

    $ F[i]=^{quadquad min}_{0<j<i,sum^{k<i}_{k=j+1}A_kleq M}{F[j]+max{A_k } } $

    这样我们发现我们得到了一种 $ n^2 $ 的做法,然后数据范围告诉我们这样还不够。我们还得优化,但是 $ wch $ 是真的不会优化了,这个式子很有单调队列的样子,但是这个 $ max{A_k } $ ,这个式子似乎无懈可击啊!(于是他看了看书,表示:考这道题我直接爆零离场算了)

    我们知道一个优秀的搜索或DP一定要尽可能去避免一些没有用的状态和决策,书上说:要保持决策集合的高度有效性和秩序性。所以我们看一看我们会不会枚举了一些没有什么用的 $ F[j] $ 。我们可以分析得出只有两种 $ F[j] $ 对我们有用:

    1. $ j $ 是满足 $ sum^{k<i}_{k=j+1}A_kleq M $ 的最小的 $ j $
    2. 我们的 $ A_j $ 是从 $ j $ 到 $ i $ 中间最大的权值

    这个其实我们静下心来想想就可以明白,如果一个数不是从它开始到第 $ i $ 个数中最大的而且它不是可枚举的最小的第 $ j $ 个数,那么它一定不是最优解,它的左边那一个 $ F[j-1] $ 一定更优,因为它比 $ F[j ] $ 小,而且最大值一样。于是我们用维护一个包含所有的高效决策的单调队列,显然 $ j $ 单调递增 $ A_j $ 单调递减。然后我们要支持及时删去对头失效的决策,然后更新队尾加元素。

    然后是这一题非常神奇的一个地方:我们要得到答案还需要 $ max{A_k } $ ,这个我们可以倍增 $ ST $ 表,但是我们分析题目性质就能发现一个跟奇妙的地方,我们的单调队列里的下一个元素就是我们要求得 $ max{A_k } $ ,这个只要想一想都知道以为我们维护的是(所有的高效决策的单调队列,并且显 $ j $ 单调递增 $ A_j $ 单调递减)。

    然后还有一个我想吐槽的地方(奈何这一题数据水),我们的单调队列的对头不一定就是我们的最佳决策,这也是说我们队列里 $ A_K $ 单调递增,但是我们求值的式子里还有一个 $ F[j] $ 这个东西是单调递减的!!!!所以我们不能妄下决定,我们还需要映射一个取值的数据结构,也就是我们的 $ set $ ,我们要让这两个东西同时增加元素又同时减少相应的元素。



    $ code: $

    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    
    #define ll long long
    #define db double
    #define inf 0x7fffffff
    #define rg register int
    
    using namespace std;
    
    int n; ll m;
    int a[100005];
    ll f[100005];
    int q[100005];
    multiset<ll >s;
    
    inline ll qr(){
    	register char ch; register bool sign=0; ll res=0;
    	while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
    	while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
    	return sign?-res:res;
    }
    
    int main(){
    	//freopen("in.in","r",stdin);
    	//freopen("cpp.out","w",stdout);
    	n=qr(); m=qr();
    	for(rg i=1;i<=n;++i) a[i]=qr();
    	rg l=1,r=0,k=1; ll tot=0;
    	for(rg i=1;i<=n;++i){
    		tot+=a[i];
    		while(tot>m)tot-=a[k++];
    		if(k>i){puts("-1");return 0;}
    		while(l<=r&&a[q[r]]<=a[i]){
    			if(r>l)s.erase(f[q[r-1]]+a[q[r]]);; --r;
    		}q[++r]=i; if(r>l)s.insert(f[q[r-1]]+a[q[r]]);
    		while(l<=r&&q[l]<k){
    			if(r>l)s.erase(f[q[l]]+a[q[l+1]]);; ++l;
    		}f[i]=f[k-1]+a[q[l]];
    		if(l<r)f[i]=min(f[i],*s.begin());
    	}printf("%lld
    ",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    tomcat配置和原理(转)
    maven install、maven clean、project clean
    spring注解的(List&Map)特殊注入功能
    React父子组件传值
    使用Ant Design的Upload上传删除预览照片,以及上传图片状态一直处于uploading的解决方法。
    使用react-redux
    URLSearchParams生成和解析URL或者参数字符串
    Ant Design的Table组件去除“取消排序”选项
    React Hooks的useState和useEffect
    webpack配置alias简化相对路径
  • 原文地址:https://www.cnblogs.com/812-xiao-wen/p/11004092.html
Copyright © 2020-2023  润新知