Codeforces Round #722 (Div. 2) ABCDE题解


A - Eshag Loves Big Arrays

贪心
题目链接
题意:给你一个序列,挑选子序列,删掉子序列中大于子序列的平均值的数,直到找不出子序列为止,求最大操作次数。

一直拿最小值和其他值构成序列
所以就是要保留最小值 a n s = ans= ans= 总数 − - 最小值的个数

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 105;
int t, n, m, a[N];
int main() {
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--) {
        cin>>n;
        m=0;
        for(int i=1; i<=n; i++) cin>>a[i];
        sort(a+1, a+1+n);
        for(int i=1; i<=n; i++) if(a[i]==a[1]) m++;
        cout<<n-m<<endl;
    }
	return 0;
}

B - Sifid and Strange Subsequences

贪心
题目链接
题意:找个最长的子序列使这个序列所有的 a b s ( a i − a j ) > = m a x ( a [ 序 列 ] ) , 1 < = i < j < = k abs(ai-aj)>=max(a[序列]),1<=i<j<=k abs(aiaj)>=max(a[])1<=i<j<=k

被题目骗到了以为和位置有关…写了结构体判断了一堆
所以就是直接 s o r t + sort+ sort+模拟题意
因为不管位置在哪里 a b s ( a i − a j ) abs(ai-aj) absaiaj是相同的

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 100005;
int t, n, m, q, ans;
ll a[N], minn;
int main() {
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--) {
        cin>>n;
        minn=1e10;
        ans=1;
        for(int i=1; i<=n; i++) cin>>a[i];
        sort(a+1, a+1+n);
        for(int i=2; i<=n; i++) {
            minn=min(minn, a[i]-a[i-1]);
            if(minn>=a[i]) ans++;
            else break;
        }
        cout<<ans<<endl;
    }
	return 0;
}

C - Parsa’s Humongous Tree

树形dp
题目链接
题意:给你一棵树,给你 i = 1 − n i=1-n i=1n的节点有个权值 a [ i ] a[i] a[i]属于 ( l [ i ] , r [ i ] ) (l[i], r[i]) (l[i],r[i])的范围,整棵树的美丽值等于所有相连节点的权值 a b s ( a [ u ] − a [ v ] ) abs(a[u]-a[v]) abs(a[u]a[v])之和,求最大美丽值

l l ll ll记得
其实最大值就是只和 l l l r r r有关 然后dfs更新子树

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 100005;
vector<int> g[N];
ll t, n, m, q, ans, dp[N][2], l[N], r[N];
void dfs(int u, int fa) {
    dp[u][0]=0;
    dp[u][1]=0;
    for(int i=0; i<g[u].size(); i++) {
        int x=g[u][i];
        if(x==fa) continue;
        dfs(x, u);
        dp[u][0]+=max(dp[x][0]+abs(l[u]-l[x]),dp[x][1]+abs(l[u]-r[x]));//dp[i][0]表示i节点取左边界
        dp[u][1]+=max(dp[x][0]+abs(r[u]-l[x]),dp[x][1]+abs(r[u]-r[x]));//dp[i][1]取右边界
    }
}
int main() {
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--) {
        cin>>n;
        memset(g, 0, sizeof g);
        for(int i=1; i<=n; i++) cin>>l[i]>>r[i];
        for(int i=1; i<n; i++){
            int u, v;
            cin>>u>>v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(1, -1);
        ans=max(dp[1][0], dp[1][1]);
        cout<<ans<<endl;
    }
    return 0;
}

D - Kavi on Pairing Duty

dp
题目链接 点击看图,求方案数

还以为推公式呢 。。没想出来
考虑 l e n len len是最长的的长度
l e n > = n + 1 len>=n+1 len>=n+1就是包含关系对应 n = 1 , n = 2 , n = 3... n=1,n=2,n=3... n=1,n=2,n=3...的所有情况总和
l e n < = n len<=n len<=n就是相同长度的交叉关系 因为每 l e n len len个相互交叉,需要 2 ∗ l e n 2*len 2len个点,一共有 2 ∗ n 2*n 2n个点,所以 l e n len len一定是 n n n的因子,方案数 + = += +=因子个数

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1000005;
const int M = 998244353;
int t, n, m, q;
ll ans, dp[N], sum;
int main() {
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i=1; i<=n; i++) {
        for(int j=i+i; j<=n; j+=i) {
            dp[j]++;//预处理因子个数
        }
    }
    sum=1;
    for(int i=1; i<=n; i++) {
        dp[i]=(dp[i]+sum)%M;//因子个数+前面的所有情况
        sum=(sum+dp[i])%M;//前缀和
    }
    cout<<dp[n]%M<<endl;
    return 0;
}

E -


总结

贪心好烂
看到dp就害怕

在这里插入图片描述

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值