CF1633D Make Them Equal 题解

题意

多测,一开始拥有一个全部为 1 1 1 的数组 a a a,以及输入两个长度一样数组 b b b c c c

可以进行 k k k 次操作:选择 a a a 数组中的一个数 a i a_i ai 和一个任意正整数 x x x,让 a i a_i ai 增加 ⌊ a i x ⌋ \left\lfloor\dfrac{a_i}{x}\right\rfloor xai

a i a_i ai 变为 b i b_i bi 的收益是 c i c_i ci,求 k k k 次以内的最大收益。

思路

这道题的 k k k 此操作看似唬人,实则为加上一个特殊的比自己小的数,考虑用 dp 来计算实现每个 b i b_i bi 需要的费用 w i w_i wi
w [ i + i / j ] = min ⁡ ( w [ i + i / j ] , w [ i ] + 1 ) w[i + i / j] = \min(w[i + i / j], w[i] + 1) w[i+i/j]=min(w[i+i/j],w[i]+1)
注意是用小推大,且变为 1 1 1 费用为 0 0 0

然后问题发生变化,已知成功变换每个数的收益 c i c_i ci 和 费用 w i w_i wi,以及可以花费 k k k,求最大收益。

01 背包。

d p [ j ] = max ⁡ ( d p [ j ] , d p [ j − w [ b [ i ] ] ] + c [ i ] ) dp[j] = \max(dp[j], dp[j - w[b[i]]] + c[i]) dp[j]=max(dp[j],dp[jw[b[i]]]+c[i])

但代码复杂度为 O ( n k ) O(nk) O(nk),即 01 背包的复杂度,超时。

考虑优化,注意到每个数的最大花费不超过 13 13 13,即所有数全部变换完成也只需要 13 n 13n 13n 的费用, 13 n 13n 13n 的最大值为 13000 13000 13000,远小于 k k k,故可以在 k k k 13 n 13n 13n 之间取最小值作为背包的容量,时间复杂度为 O ( n 2 ) O(n^2) O(n2) 左右。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e3 + 10, M = 1e6 + 10, inf = 4e9;

int t, n, k;
int b[N], c[N], w[M]; 
int dp[M];

void work() {
	memset(w, 0x3f, sizeof w);
	w[1] = 0;
	for(int i = 1;i <= 1000;i++) {
		for(int j = 1;j <= i;j++) {
			w[i + i / j] = min(w[i + i / j], w[i] + 1);
		}
	}
}

void _dp() { // 01 背包
	memset(dp, 0, sizeof dp);
	for(int i = 1;i <= n;i++) {
		for(int j = k;j >= w[b[i]];j--) {
			dp[j] = max(dp[j], dp[j - w[b[i]]] + c[i]);
		}
	}
}

signed main() { 
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	
	work(); // 预处理每个数的花费
	
	cin >> t;
	while(t--) {
		cin >> n >> k;
		for(int i = 1;i <= n;i++) {
			cin >> b[i];
		}
		for(int i = 1;i <= n;i++) {
			cin >> c[i];
		}
		
		k = min(k, n * 13); // 优化
		_dp();
		
		cout << dp[k] << endl;
	}
	
	return 0;
}
  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值