• Codeforces 356D 倍增优化背包


    题目链接:http://codeforces.com/contest/356/problem/D

    思路(官方题解):http://codeforces.com/blog/entry/9210

    此题需要注意,直接用01背包会TLE, 需要看成多重背包,倍增优化一下。

    代码:

    #include <bits/stdc++.h>
    #define LL long long
    #define pii pair<int, int>
    using namespace std;
    const int maxn = 70010;
    bitset<maxn> dp;
    pii a[maxn];
    int ans[maxn], pre[maxn], numl[maxn], numr[maxn], cnt[maxn];
    vector<int> re[maxn];
    set<pii> s;
    set<pii>::iterator it;
    bool v[maxn];
    int main() {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", &a[i].first);
    		a[i].second = i;
    		cnt[a[i].first]++;
    	}
    	sort(a + 1, a + 1 + n);
    	reverse(a + 1, a + 1 + n);
    	dp[a[1].first] = 1;
    	cnt[a[1].first]--;
    	int pos = -1;
    	for (int i = 2; i <= n && dp[m] == 0; i++) {
    		int t = cnt[a[i].first];
    		for (int k = 1; t; k <<= 1) {
    			k = min(t, k);
    			for (int j = m; j >= a[1].first + a[i].first * k; j--) {
    				if(dp[j] == 0 && dp[j - a[i].first * k] == 1) {
    					dp[j] = 1;
    					numl[j] = i, numr[j] = i + k - 1;
    					pre[j] = j - a[i].first * k;
    				}
    			}
    			t -= k;
    			i += k;
    			if(dp[m] == 1) {
    				pos = i;
    				break;
    			}
    		}
    		i--;
    	}
    	if(dp[m] == 0) {
    		printf("-1
    ");
    		return 0;
    	}
    	for (int i = m; i > a[1].first; i = pre[i]) {
    		for (int j = numl[i]; j <= numr[i]; j++) {
    			v[j] = 1;
    			s.insert(a[j]);
    		}
    	}
    	s.insert(a[1]);
    	v[1] = 1;
    	for (int i = 1; i <= n; i++) {
    		if(v[i]) continue;
    		it = s.lower_bound(make_pair(a[i].first, -1));
    		pii tmp = *it;
    		s.erase(it);
    		tmp.first -= a[i].first;
    		ans[tmp.second] -= a[i].first;
    		re[tmp.second].push_back(a[i].second);
    		s.insert(tmp);
    		s.insert(a[i]);
    	}
    	for (int i = 1; i <= n; i++) {
    		ans[a[i].second] += a[i].first;
    	}
    	for (int i = 1; i <= n; i++) {
    		printf("%d ", ans[i]);
    		printf("%d", re[i].size());
    		for (int j = 0; j < re[i].size(); j++) {
    			printf(" %d", re[i][j]);
    		}
    		printf("
    ");
    	}
    }
    

      

  • 相关阅读:
    Scrapy框架实现持久化存储
    Scrapy框架的介绍和基本使用
    处理页面动态加载数据
    爬虫数据解析
    Python爬虫基础
    Flask详解(下篇)
    Flask详解(中篇)
    CentOS 中的性能监测命令vmstat
    CentOS 7安装MySQL 8.0.15
    CF B.Kind Anton(4月8号)
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/11139053.html
Copyright © 2020-2023  润新知