前言:
感觉是先天caibi圣体,每次准备好好的打,就被狠狠卡住里,幸好最后比赛unrated了,不然直接掉打分,唉,要是掉了不知道多久能回来,唉。补题了
A.Cidoai的幂次序列
题目方程乍一看很唬人,实际上带一下样例就会明白怎么回事
2244 = pow(2,3) + pow(3,7) +pow(7,2)
恰好就是一个循环,妙!
那就直接输入1和n-1就行了(也就会这一点了)
void solve(){
LL n,k;
cin>>n>>k;
cout<<2<<endl;
cout<<1<<" "<<n-1<<endl;
}
B Cidoai的平均数对
直接在这里卡到爆,一直在想什么背包有关平均值,不知道怎么处理平均,赛后看群里大佬提了一嘴,就是化把所有容积减去k这个数,就转化成保证容积为0的01背包,看完想了一下,几分钟就把题a掉了(思路没想到,还是练少了。。。)
先把负的贪心进去,再累计转为背包容积,然后把正的往里狠狠地塞就行了
int main() {
int n,k;
cin>>n>>k;
vector<int> a(n+1,0),b(n+1,0),dp(250000,0);
int cnt = 0;
int ans = 0;
int num = 0;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
b[i]-=k;
if(b[i]<=0) {
cnt++;
num+=abs(b[i]);
ans+=a[i];
}
}
int op = 0;
vector<int> c(n+1,0),d(n+1,0);
for(int i=1;i<=n;i++){
if(b[i]>0){
c[++op]=a[i];
d[op]=b[i];
}
}
for(int i=1;i<=op;i++){
for(int j = num;j>=d[i];j--){
dp[j] = max(dp[j] , dp[j-d[i]]+c[i]);
}
}
cout<<dp[num]+ans;
}
C Cidoai的树上方案
重点还是状态转移方程的书写,还有题意的理解 dp设置01状态来转移
对于每个点,都要赋初值1,用不用都算一种情况,最后算的时候要乘起来,因为孩子都是可以使用,之间是乘的关系
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int p = 998244353;
const int N = 2e6 + 10;
vector<LL> a(N, 0);
vector<LL> g[N];
vector<vector<LL>> dp(N, vector<LL>(2, 0));
LL res = 1 ,ans = 1;
void dfs(int x) {
dp[x][0] = 1;
dp[x][1] = 1;
for (int i = 0; i < g[x].size(); i++) {
int son = g[x][i];
dfs(son);
dp[x][0] = (dp[x][0]%p*(dp[son][0]+dp[son][1])%p)%p;
dp[x][1] = ((dp[x][1]%p)*(dp[son][0]%p))%p;
}
}
int main() {
int n;
cin >> n;
for (int i = 2; i <=n; i++) {
cin >> a[i];
g[a[i]].push_back(i);
}
dfs(1);
cout << (dp[1][1]+dp[1][0])%p << endl;
return 0;
}