牛客练习赛128(ABCD、思维、01背包、树上DP、并查集)

牛客练习赛128(ABCD、思维、01背包、树上DP、并查集)


非数论选手,直接放弃最后两题


A. Cidoai的幂次序列(思维)

考虑特殊情况:1x = 1。这时,如果可以凑出一个 n-1 即可,显然 (n-1){1%2} = n-1。

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

int main(){
    
    ll n, k;
    cin >> n >> k;
    
    cout << 2 << endl;
    cout << n-1 << " " << 1 << endl;
    
    return 0;
}

B. Cidoai的平均数对(01背包)

第一想法,DP,算时间复杂度,O(5004),超时,需要优化。

考虑平均数约束的作用。首先,bi 不大于 k 的物品,全部选取。这时对于已经被选择的物品,记 x = ∑ ( k − b i ) x = \sum(k - b_i) x=(kbi),可以把问题转化为一个容量为 x 的01背包问题。

#include<bits/stdc++.h>

using namespace std;

const int maxn = 505;

int a[maxn], b[maxn];
int dp[maxn * maxn];

int main(){
    
	int n, k;
	cin >> n >> k;
	for(int i = 1; i <= n; i++) cin >> a[i] >> b[i];
	for(int i = 1; i <= n; i++) b[i] -= k;
	
	int sum_a = 0, sum_b = 0;
	for(int i = 1; i <= n; i++){
		if(b[i] < 0){
			sum_a += a[i];
			sum_b += -1 * b[i]; // 富裕的体积收集起来
		}
	}
	
	for(int i = 1; i <= n; i++){    // 01背包往富裕的体积里装
		if(b[i] < 0) continue;
		for(int j = sum_b; j >= b[i]; j--){
			dp[j] = max(dp[j], dp[j-b[i]] + a[i]);
		}
	}
	
	c
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值