首页 > 其他分享 >[IOI2014]friend 朋友

[IOI2014]friend 朋友

时间:2022-10-17 16:00:44浏览次数:75  
标签:个点 朋友 IOI2014 int IOI 权值 friend

题目传送门

似乎是我的第一篇 IOI 题解?

思路

虽然说是 IOI 题,但是其实并没有那么难。

这个题目描述比较杂乱,简单的描述就是:给你一些关系,你需要选出一些点,使这些点的权值和最大,并且这些点之间两两都没有关系。

似乎像是一个 DP,所以我们不妨设出状态:\(f_{i,0/1}\) 表示第 \(i\) 个点,选/不选的最大权值和。

设 \(w_i\) 表示第 \(i\) 个点的权值,\(x\) 表示当前的主持人。

我们来一种一种操作分析:

  • IAmYourFriend:就是一个简单的没有上司的舞会,\(f_{x,0}=w_x+f_{i,1},f_{x,1}=\max(f_{i,0},f_{i,1})\)。
  • MyFriendsAreYourFriends:意为 \(i\) 是 \(x\) 所有朋友的朋友,那么既然选了 \(i\),那么 \(x\) 的朋友必须不选,那么 \(x\) 显然可以选,所以 \(f_{x,0}=\max(w_x+f_{i,0},w_x+f_{i,1},f_{x,1}+f_{i,0},f_{x,1}+f_{i,1}),f_{x,1}+=f_{i,1}\)。
  • WeAreYourFriends:相当于第一种情况和第二种情况拼起来,不再赘述。

代码

#include<bits/stdc++.h>
using namespace std;
int const N=1e6+10;
int f[N][2],co[N],ho[N],pr[N];
int findSample(int n,int confidence[],int host[],int co[]){
    for (int i=0;i<n;++i) f[i][0]=confidence[i];
    for (int i=n-1;i;--i){
        int x=host[i];
        if (co[i]==0)
            f[x][0]+=f[i][1],f[x][1]+=max(f[i][0],f[i][1]);
        else if (co[i]==1)
            f[x][0]+=max(f[i][0],f[i][1]),f[x][0]=max(f[x][0],f[x][1]+max(f[i][1],f[i][0])),f[x][1]+=f[i][1];
        else if (co[i]==2)f[x][0]+=f[i][1],f[x][0]=max(f[x][0],f[x][1]+f[i][0]),f[x][1]+=f[i][1];
    }
    int ans=0;
    for (int i=0;i<n;++i) ans=max(ans,f[i][0]),ans=max(ans,f[i][1]);
    return ans;
}

标签:个点,朋友,IOI2014,int,IOI,权值,friend
From: https://www.cnblogs.com/tx-lcy/p/16799506.html

相关文章