文章目录
牛客练习赛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=∑(k−bi),可以把问题转化为一个容量为 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