【好题】组合数学——ICPC GNYR 2019 J

/*
首先推出一个结论:外圈有n个点的图答案必定是 n*f(n)的形式,因为每转过一个角度都会计数一次 
然后来考虑f(n):显然所有可行的解中只能有一个圈,大小为k的圈必定只会有一种连接的方法
    所以只要考虑剩下n-k个圈外点的连接种数即可
设i个圈外点的连接方案数是g(i),同时我们以顺时针把这些圈外点排好 
    每个点有三种连接方法:和中心连(向内),向逆时针连,向顺时针连 
    求g(i+1)等价于在g(i)的基础上,又在顺时针处新加了一个圈外点
    这个圈外也点有三种连接方式 3*g(i) 
    但是当其逆时针连边时,如果第i个圈外点向顺时针连边,那么这条边就重合了,要减去所有这种情况 g(i-1) 
初始状态:g(0)=1,g(1)=3 
*/
#include<bits/stdc++.h>
using namespace std;
#define mod 100007

int n,g[100005];

int main(){
    cin>>n;
    g[0]=1;g[1]=3;
    for(int i=2;i<=n;i++)
        g[i]=(3*g[i-1]-g[i-2]+mod)%mod;
    //for(int i=0;i<=n;i++)cout<<g[i]<<" ";
    
    int ans=1;//特殊情况:中间点被隔开 
    for(int i=0;i<=n-2;i++)
        ans=(ans+g[i])%mod;
    cout<<ans*n%mod<<'
';
}
原文地址:https://www.cnblogs.com/zsben991126/p/12775113.html