洛谷 P1416 攻击火星

题目链接在这儿!

题目描述

一群外星人将要攻击火星。

火星的地图是一个n个点的无向图。这伙外星人将按照如下方法入侵,先攻击度为0的点(相当于从图中删除掉它),然后是度为1的点,依此类推直到度为n-1的点。

所有的点度统计是动态统计的。(一个点删掉后,与之相连的点的点度都会-1)。外星人攻击度为某个数的点时是同时攻击的。

你需要设计这个图的边的方案来使得未被攻击的点最多。

输入格式

输入文件包含一行一个整数n。

输出格式

一行一个整数,表示最多的最后未被攻击的点。

输入输出样例

输入 #1
3
输出 #1
1

说明/提示

【样例解释】

①-②-③,这样首先删掉度为1的①和③,此时②度数为0,不会被删去。

【数据范围】

对于20%的数据1<=n<=10

对于100%的数据1<=n<=50000

思路:

大家看了这道题,是不是有一点懵逼的感觉?

n<=50000?! 这建图至少要二维数组呀!

还有,这O(n2)算法过不了啊!

但是,当你看到代码时,你肯定会认为:

你这几年的数学白学了吧!

(提示:算法标签为模拟与构造)

(建议你想一想再看代码,因为这是一道普及-的题目!)

(我说这题O(1)你们信吗?)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 int main()
 5 {
 6     cin>>n;
 7     if(n==1) cout<<0;
 8     else cout<<n-2;
 9         return 0;
10 }
牛X代码

(看了代码心情怎么样?)

 下面我们就具体证明一下:

若n==1或n==0,则显然,ans=0;

当n==2时,则也显然,ans=0;

当n==3时,要么你让他们变成一个三角形,要么你让他们变成一条线。

显然一条线更优,所以ans=1;

当n>=4时,假设ans==n-1(显然ans<n),

因为最开始总会删除一个或多个点,所以你必须删除一个点且让其他所有的点的度都减1,让其他的点防止被删除。

所以你必须将那个要被删除的点与其他所有的相连,以达到目的。

但这个点的度就变成了n-1,所以它的度一定==max(度)。

这说明要么第一个删的不是它,要么它和其他一个或多个点一起删掉。

显然,与假设时的条件不符,矛盾。

所以假设不成立。

所以我们考虑ans==n-2;(这时若ans可以等于n-2的话,就一定是最优解)

当n==4时(n==3和n==2的情况我们已知符合ans==n-2),你可以如下图,用一条线,删除两边的端点。

所以ans==2==n-2;

当n==5时,你可以像下图一样,构造一个五边形,然后选一个点,与不与它相邻的两个点相连。

 当n>=6时,我们可以将n个点分成两种点,第一种有2个点,第二种有n-2个点。

因为n>=6,所以n-2>=4。

我们将所有属于第二种的n-2个点围成一个n-2边形并将所有的对角线以及n-2条边连接。(以下的图都以n==6为例)

这时,在第二种点当中,每一个点都与其他n-3个点连接,所以他们的度都为n-3;

然后,我们再让剩下第一种的两个点与那n-2个点连接。

这时我们就会先将第一种的两个点删除。

于是原图就变成了这样:

这时我们发现,已经不需要删点了。所以结束,ans==n-2,符合规律。

本人总结:

这一题的难点就在要发现规律,自己如果在数据的枚举以及个人的感觉上认为是对的,就应该竭力去验证(本人简称“瞎蒙乱猜法”)。

怎么样? 涨知识了吧!!!

原文地址:https://www.cnblogs.com/xinxiyuan/p/11305382.html