zoukankan      html  css  js  c++  java
  • JZOJ6358. 【NOIP2019模拟2019.9.15】小ω的仙人掌

    Description

    在这里插入图片描述
    s<=1e4,ai<=w<=5e3,k<=1e9

    Solution

    • 如果[l,r]合法,那么[l,r+1]也合法。
    • 所以可以用两个指针来维护,合法l++,不合法r++。
    • 现在我们要考虑对于指针l,r,判断[l,r]是否合法。
    • 我们想要维护[l,r]的背包的情况,往后加一个是w的,但是我们怎么删除头呢?
    • 有一种很巧妙的方法,我们使用双栈,将[l,r]分成[l,mid],[mid+1,r]两个区间,对于[l,mid]从后往前维护背包的数组,直接退就好了,对于[mid+1,r]维护前往后的。
    • 如果左边的栈没有了,就暴力将[mid+1,r]全部变成左边的栈。
    • 这样就是O(sw)的了。
    • 这种方法的性质为:O(w)判断,O(w)转移。
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define maxn 10005
    #define maxm 5005
    #define inf 1e9+5
    using namespace std;
    
    int n,m,lim,i,j,k,a[maxn],b[maxn],ans;
    int f[maxn][maxm],l,r,mid; 
    
    void read(int &x){
    	x=0; char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar());
    	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    }
    
    int check(){
    	if (mid==r) return f[l][m]<=lim;
    	if (mid<l) return f[r][m]<=lim;
    	for(i=0;i<=m;i++) if (f[l][i]+f[r][m-i]<=lim)
    		return 1;
    	return 0;
    }
    
    int main(){
    	freopen("cactus.in","r",stdin);
    	freopen("cactus.out","w",stdout);
    	read(n),read(m),read(lim);
    	for(i=1;i<=n;i++) read(a[i]),read(b[i]);
    	for(i=1;i<=n;i++) for(j=0;j<=m;j++) f[i][j]=inf;
    	l=1,r=0,mid=0,ans=n+1;
    	while (r<=n){
    		if (check()) {
    			ans=min(ans,r-l+1);
    			if (l>mid) {
    				l++;
    				mid=r;
    				for(i=0;i<=m;i++) f[r][i]=inf;
    				f[r][a[r]]=b[r],f[r][0]=0;
    				for(i=r;i>l;i--) for(j=0;j<=m;j++) {
    					f[i-1][j]=f[i][j];
    					if (j>=a[i-1])
    					f[i-1][j]=min(f[i-1][j],f[i][j-a[i-1]]+b[i-1]);
    				}
    			} else l++;
    		} else{
    			if (r==n) break;
    			if (r==mid) {
    				r++;
    				f[r][a[r]]=b[r];
    				f[r][0]=0;
    			}  else {
    				r++;
    				for(i=0;i<=m;i++) {
    					f[r][i]=f[r-1][i];
    					if (i>=a[r])
    						f[r][i]=min(f[r][i],f[r-1][i-a[r]]+b[r]);
    				}
    			}
    		}
    	}
    	if (ans==n+1) printf("-1"); else printf("%d",ans);
    }
    
  • 相关阅读:
    HDU 1251 统计难题(Trie)
    归并排序求逆序数
    HDU 4565 So Easy(矩阵解公式)
    HDU 3306 Another kind of Fibonacci(矩阵+ll超时必须用int&输入必须取模&M必须是int类型)
    IDEA设置一直显示行号
    IntelliJ Idea 常用快捷键列表
    Intellij IDEA快捷键(转)
    Springmvc返回JSON格式到页面中文乱码问题
    java中Date类型无法获取数据库时分秒问题解决方法
    使用阿里大于实现手机验证码
  • 原文地址:https://www.cnblogs.com/DeepThinking/p/13090964.html
Copyright © 2011-2022 走看看