AGC16E Poor Turkeys

本文探讨了一道关于多只鸡在特定规则下能否共存的算法问题,通过递推、模拟与贪心策略,设计了一个高效解决方案。利用布尔矩阵记录每只鸡的生死状态,实现了时间倒流的概念,确保任意两只鸡不会因相互保护而陷入矛盾,最终统计出能够共存的鸡的组合数量。

1464677-20180926161806220-747722710.png

输入样例:

10 10
8 9
2 8
4 6
4 9
7 8
2 8
1 8
3 4
3 4
2 7

输出样例#6:

5


话说这题虽然不是很OI但是确实挺锻炼思维的

一开始以为是用并查集之类的东西维护

然后想了好久还是煤油想出来

正解是一个递推?模拟?贪心?

维护n个集合

我们设\(f[i][j]\)表示如果要让\(i\)活到最后\(j\)应不应该死

可以考虑时间倒流

一开始\(f[i][i]=true\)

然后倒着循环操作

如果两只鸡有一只已经死了,那么另一只在这回合必须死

如果两只鸡有两只都活着,就随便死一个

如果两个都死了,那么这个鸡\(i\)就只能死了

最后查询的时候如果两个集合有交集

那这两只鸡就不能同时活到最后

因为如果有交集说明有一个鸡同时要给两只鸡当挡箭牌

但是一只鸡只能死一次

统计一下答案就好辣

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
# define LL long long
const int M = 405 ;
const int N = 100005 ;
using namespace std ;
inline int read() {
    char c = getchar() ; int x = 0 , w = 1 ;
    while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
    while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
    return x*w ;
}
LL Ans ;
int n , m ;
int a[N] , b[N] ;
bool f[M][M] , die[M] ;
int main() {
    n = read() , m = read() ;
    for(int i = 1 ; i <= m ; i ++) 
        a[i] = read() , b[i] = read() ;
    for(int i = 1 ; i <= n ; i ++) {
        f[i][i] = true ;
        for(int j = m ; j >= 1 ; j --) {
            bool x = f[i][a[j]] , y = f[i][b[j]] ;
//  x : 目前a[j]是否死了 
//  y : 目前b[j]是否死了
            if(x & y) { die[i] = true ;  break ; }
            else if(x) f[i][b[j]] = true ;
            else if(y) f[i][a[j]] = true ;
        }
    }
    for(int i = 1 , tot ; i < n ; i ++) {
        if(die[i]) continue ;
        for(int j = i + 1 ; j <= n ; j ++) {
            if(die[j]) continue ;
            tot = 1 ;
            for(int k = 1 ; k <= n ; k ++)
                if(f[i][k] & f[j][k])
                    tot = 0 ;
            Ans += tot ;
        }
    }
    cout << Ans << endl ;
    return 0 ;
}

转载于:https://www.cnblogs.com/beretty/p/9707757.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值