luogu P11055 Yet another ZP problem

前言

Yet another 系列特有的难想。

Sol

Motivation:如果 \(m=0\) 呢,边数的下界是多少?

考虑每次解决两个单点限制,即连 \((A,B)\)\(A、B\) 都没出现过,但是当 \(n\) 为奇数的时候,最后一条边解决一个单点限制。

这样 \(\lvert E\rvert=\lceil \frac{n}{2}\rceil\),即为边数下界。


数据范围:\([l_i,r_i]\ne [1,n]\)

这不仅避免了无解的情况。

Motivation:我能不能运用这个条件?

对于每个区间,必有如果一个点紧贴起终点,那么另一个点必然不紧贴。也就是说只需要连 \((1,n)\) 这一个边即可解决所有紧贴的区间。

接下来问题规模缩小到 \([2,n-1]\),虽然没有了上文的数据限制条件,但是可以一个点连向 \([2,n-1]\) 之外。于是对于 \([2,n-1]\) 就需要连向外面,但是实际我们在最后一次需要连向外边时一次性解决所有连向外面的边(即外面的边连向 \(1\)\(n\)),然后按照刚刚的连边 \((2,n-1)\),接着又继续解决更小的问题。在最后一个子问题解决所有连外边问题就行(对于奇数最后子问题是 \(1\),因为长度只有一,直接连向外面即可)。对于奇数,紧贴下界,无需证明即最优。对于偶数,上述构造方式为下界加一。


Motivation:偶数是不是不对?我不会证明它是对的!我讨厌偶数!能不能变成奇数?

孤立最左或最右点,这样变为奇数问题,但是无 \([l_i,r_i]\ne [1,n]\),依旧是之前的思路,在最后的子问题解决所有连向外面的问题。但是此时的外面是孤立的点(就算不需要连外面的点,最后也要连孤立点,不然孤立点谁来连?)。此时次数也紧贴下界!

做完了!

Code

/*
One, Two, Three, Four
一,二,三,四

Five, Six, Seven, Eight
五,六,七,八

Nine!
九!

You win!
你赢了!

Perfect~
完美! 

Go for another one!!
去另一个!!
*/
#include <bits/stdc++.h>
using namespace std;
int n,i,t;
signed main() {
    cin>>n;
    cout<<(n+1>>1)<<endl;
    for(i=((n&1)?1:2),t=1;t<=(n-1)/2;i++,t++) cout<<i<<' '<<n+1+(!(n&1))-i<<endl;
    cout<<1<<' '<<i<<endl;
    return 0;
}
posted @ 2024-09-18 19:39  PM_pro  阅读(15)  评论(0)    收藏  举报