首页 > 其他分享 >Gym101064L The Knapsack problem

Gym101064L The Knapsack problem

时间:2023-10-16 14:47:21浏览次数:46  
标签:typedef frac Gym101064L long maxn Knapsack problem define

CF 传送门

发现物品的体积很小,尝试从此处入手。

设 \(K\) 为最大的物品体积。把背包体积 \(m\) 分成差不超过 \(K\) 的两部分,然后合并。这样需要求出 \(f(\frac{m}{2} - K \sim \frac{m}{2} + K)\)。

递归地,可以发现需要求出 \(f(\frac{m}{2^k} - K \sim \frac{m}{2^k} + K)\)。最后再合并即可。

code
// Problem: L. The Knapsack problem
// Contest: Codeforces - 2016 USP Try-outs
// URL: https://codeforces.com/gym/101064/problem/L
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 2020;

ll n, m, K, a[maxn], b[maxn], c[maxn], f[maxn], g[99][maxn];

void solve() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld%lld", &a[i], &b[i]);
		K = max(K, a[i]);
	}
	int tot = 0;
	while (m) {
		c[++tot] = m - K;
		m >>= 1;
	}
	for (int i = 1; i <= n; ++i) {
		for (int j = a[i]; j <= K * 2; ++j) {
			f[j] = max(f[j], f[j - a[i]] + b[i]);
		}
	}
	for (int i = tot; i; --i) {
		for (int j = c[i]; j <= c[i] + K * 2; ++j) {
			if (j <= K * 2) {
				g[i][j - c[i]] = (j < 0 ? 0 : f[j]);
			} else {
				for (int k = (j - K) / 2; k <= j / 2; ++k) {
					g[i][j - c[i]] = max(g[i][j - c[i]], g[i + 1][j - k - c[i + 1]] + g[i + 1][k - c[i + 1]]);
				}
			}
		}
	}
	printf("%lld\n", g[1][K]);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:typedef,frac,Gym101064L,long,maxn,Knapsack,problem,define
From: https://www.cnblogs.com/zltzlt-blog/p/17767276.html

相关文章

  • ABC159F Knapsack for All Segments
    原题翻译\(O(n^3)\)的朴素\(dp\)是simple的考虑定义一个子序列是”好的子序列”当且仅当\(a_l\)和\(a_r\)都在子序列中,容易发现他对答案的贡献是包含他的区间,即\(l\times(n-r+1)\)先说我自己的做法:设\(dp_{i,j}\)表示强制以\(i\)结尾,子序列和为\(j\)的......
  • GDCPC2023 L Classic Problem
    洛谷传送门CF传送门对于一个点\(x\),若\(\existsi,u_i=x\lorv_i=x\),则称\(x\)为特殊点,否则为一般点。首先发现,对于极长的一段\([l,r]\)满足\(l\simr\)均为一般点,那么可以连边\((l,l+1),(l+1,l+2),\ldots,(r-1,r)\),然后把\([l,r]\)缩成一......
  • tp5 php 阿里OS RequestCoreException: cURL error: SSL certificate problem: certif
    出现这种情况,肯定是域名SSL证书过期。现在出现问题:提交表单出现这种情况,网址不是https的,之前一直也没有问题,一开始想不通网址都不是HTTPS为什么还会有SSL证书的问题,检查了下发现上传中图片是上传到阿里OSS的(https://img.oss.xxx.com),里边就用到了HTTPS域名,原来是这样里,一查发现过......
  • 题解 CF457F 【An easy problem about trees】
    尝试理解,感谢cz_xuyixuan的题解。算作是很多情况的补充说明。我们不妨先二分答案,将\(\gemid\)的设为\(1\),\(<mid\)的设为\(0\),于是问题转化为了权值均为\(0/1\)的版本。我们称一棵树的大小为其非叶节点数。我们称一棵大小为奇数的树为奇树,大小为偶数的树为偶树。对......
  • 2023-02-06Fix dual system time problem copy
    +++title="Fixdualsystemtimeproblem"description=""date=2023-02-06T14:21:50+08:00featured=falsecomment=truetoc=truereward=truecategories=[""]tags=["ubuntu"]series=[]images=[]+......
  • 题解 AGC015D【A or...or B Problem】
    题解AGC015D【Aor...orBProblem】problem从\(\geA\)且\(\leB\)的整数中选择一个或多个,把这些整数按位或,求一共有多少种可能的结果。\(1\leA\leB\le2^{60}\)solution首先暴力怎么写呢?FWT。设序列\(a_i=[L\leqi\leqR]\),然后对它FWT-or之后自己乘几倍,再翻回......
  • 题解 P9701【[GDCPC2023] Classic Problem】
    题如其名,确实挺经典的。我们称边权在输入中给定的边为特殊边,其它边为平凡边。称特殊边涉及到的点为特殊点,其它点为平凡点。显然,对于连续的若干平凡点\([l,r]\),他们内部的最优连边方式就是连成一条链,花费\(r-l\)的代价。我们先把这样的代价加到答案中,然后将极长连续平凡点缩成......
  • AtCoder Beginner Contest 288 Ex A Nameless Counting Problem
    洛谷传送门AtCoder传送门考虑到规定单调不降比较难搞。先设\(g_t\)为长度为\(t\)的满足条件的序列个数(可重且有顺序)。求这个可以设个dp,\(f_{d,i}\)表示考虑到从高到低第\(d\)位,当前\(t\)个数中有\(i\)个仍然顶上界,并且之前的位都满足异或分别等于\(X\)的限制。......
  • [ABC256Ex] I like Query Problem
    原题传送门题意区间整除,区间推平,查询区间和。大家好啊,我喜欢暴力乱搞,所以这题我用暴力乱搞AC了。首先观察到操作\(1\)的性质:首先保证了除数至少为\(2\)(不然是\(1\)或者\(0\)的话也没啥意义啊),所以对一个数不断进行操作的话,每次数的大小至少会减少一半,减小到\(0\)之......
  • Problem - 616C - Codeforces
    Problem-616C-CodeforcesC.TheLabyrinth如果是直接对\(*\)去跑dfs或者bfs的话无疑是会超时的既然如此,那我们可以去对\(.\)跑搜索,将各个连通的\(.\)块标号并计算出连通块内的点的数量,然后去遍历\(*\)的时候只需要上下左右跑一下计算即可啊,在\(bfs\)或\(dfs\)的时......