zoukankan      html  css  js  c++  java
  • HDU多校联赛2019Round3. 1007(HDU6609) Find the answer 题解

    原题链接:Find the answer
    题目大意:给你(n)个数,每一个数不超过(m),对于每一个数(a_i),你要从(a_1,a_2,...,a_{i-1})中删掉一些数,使得 $$ {{sum_{j=1}^i {a_j}} leq m} $$,求对于每一个(i in [1,n]),求要删掉的数的最小数量。
    题解:我们先考虑只有一次询问的情况,肯定是贪心,将最大的删去,一次的复杂度为(O(n))(n)次的复杂度便为(O(n^2)),但是,这是每一次重新算,我们发现,在大部分情况下,第(i)个删除的数与第(i+1)个删除的数有很大部分是一样的,改变就是新增的(a_i),所以我们就可以考虑莫队算法,至于维护序列有序,可以用set来完成,复杂度不大靠谱,但是能过。
    代码:

    #include <set>
    #include <cstdio>
    using namespace std;
    #define Maxn 200000
    #define ll long long
    int w[Maxn+5];
    int n,m;
    multiset<int> st;
    int main(){
    	int t;
    	scanf("%d",&t);
    	ll sum;
    	multiset<int>::iterator it_1;
    	int ans;
    	while(t--){
    		st.clear();
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=n;i++){
    			scanf("%d",&w[i]);
    		}
    		sum=0;
    		printf("0 ");
    		st.insert(w[1]);
    		sum+=w[1];
    		it_1=st.end();
    		ans=0;
    		for(int i=2;i<=n;i++){
    			sum+=w[i];
    			while(sum>m){
    				it_1--;
    				ans++;
    				sum-=(*it_1);
    			}
    			printf("%d ",ans);
    			st.insert(w[i]);
    			if(it_1!=st.end()&&w[i]>=(*it_1)){
    				sum-=w[i];
    				ans++;
    				while(sum+(*it_1)<=m){
    					sum+=(*it_1);
    					ans--;
    					it_1++;
    				}
    			}
    		}
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    shader变体
    正向渲染
    LWPR
    blend
    slua
    unity
    jsBridge
    浏览器
    数据运营系统
    广告
  • 原文地址:https://www.cnblogs.com/withhope/p/11268580.html
Copyright © 2011-2022 走看看