• 【EOJ12月月赛】F、天桥


    F.天桥

    题目传送门

    https://acm.ecnu.edu.cn/contest/340/problem/F/

    思路

    给你n个块(n为偶数),要对这n个块进行上色,有k种颜色可以选取,上的颜色需要两两配对并且不能交叉。若第x与y同色,u与v同色,当且仅当x<u<y<v时被认为是交叉。

    g[i]长度为2i的合法染色序列个数 f[i]长度为2i 该序列的贪心括号序列中最外层括号的颜色不为某个特定色的方案数

    因此我们可以得出转移方程

    g[i]=(k-1)(sum^{n}_{j=1})g[j]g[i-j-1]

    f[i]=k(sum^{n}_{j=1})g[j]f[i-j-1]

    代码实现

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    using namespace std;
    inline ll read(){
    	ll f=0,num;
    	char ch;
    	while(ch=getchar(),!isdigit(ch))if(ch=='-')f=1;num=ch-'0';
    	while(ch=getchar(), isdigit(ch))num=num*10+ch-'0';
    	return f?-num:num;
    }
    const int mod = 1e9 + 7;
    const int N = 3e3 + 3;
    ll f[N],g[N];
    //g[i]长度为2i的合法染色序列个数  f[i]长度为2i  该序列的贪心括号序列中最外层括号的颜色不为某个特定色的方案数
    
    int main(){
    	int n,k;
    	n = read();k = read();
    	g[0] = 1;
        for (int i = 1; i <= n / 2; i++) {
            for (int j = 0; j <= i - 1; j++) {
                g[i] = (g[i] + 1ll * (k - 1) * g[i - j - 1] * g[j] % mod ) % mod;
            }
        }
        f[0] = 1;
        for (int i = 1; i <= n / 2; i++) {
            for (int j = 0; j <= i - 1; j++) {
                f[i] = (f[i] + 1ll * k * g[i - j - 1] * f[j] % mod ) % mod;
            }
        }
    	cout<<f[n/2]<<endl;
      
    	return 0;
    }
    
  • 相关阅读:
    各地电信运营商插广告赚钱,北京联通也不甘落后
    也谈Server Limit DOS的解决方案
    Still Believe
    无奈小虫何
    好朋有也有类别
    无为而治
    青鸟随想
    落寞时分
    网站开发学习路线和资料
    C++实例 添加快捷键表
  • 原文地址:https://www.cnblogs.com/Shayndel/p/14059825.html
Copyright © 2020-2023  润新知