zoukankan      html  css  js  c++  java
  • #01背包,容斥,排列组合#洛谷 5615 [MtOI2019]时间跳跃

    题目


    分析

    不是凸多边形当且仅当边数小于2或者最长边大于等于其余边之和,
    那么容斥一下,首先总权值为

    [sum_{i=1}^nC(n,i) imes i=nsum_{i=1}^nC(n-1,i-1)=nsum_{i=0}^{n-1}C(n-1,i)=n2^{n-1} ]

    然后设 (f[n]) 表示等于 (n) 的方案数,(dp[n]) 表示等于 (n) 的权值和,

    那么 (dp[n]=dp[n-x]+f[n-x]) 就可以实现转移,每次枚举新的最长边时统计一下方案数即可


    代码

    #include <cstdio>
    #include <cctype>
    using namespace std;
    const int N=5011,mod=1000000007;
    const int i2=(mod+1)>>1;
    int f[N],dp[N],two[N],ans[N],iwo[N];
    int iut(){
    	int ans=0; char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    	return ans;
    }
    void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    void Mo(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
    void Pro(int n){
    	f[0]=two[0]=iwo[0]=1;
    	for (int i=1;i<=n;++i) ans[i]=1;
    	for (int i=1;i<=n;++i) iwo[i]=1ll*i2*iwo[i-1]%mod;
    	for (int i=1;i<=n;++i){
    		for (int j=1;j<=i;++j) Mo(ans[i],(dp[j]+f[j])%mod);
    		for (int j=n;j>=i;--j) Mo(dp[j],(dp[j-i]+f[j-i])%mod);
    		for (int j=n;j>=i;--j) Mo(f[j],f[j-i]);
    	}
    	for (int i=1;i<=n;++i) two[i]=2ll*two[i-1]%mod;
    	for (int i=1;i<=n;++i) Mo(ans[i],ans[i-1]);
    	for (int i=1;i<=n;++i) ans[i]=(1ll*i*two[i-1]%mod-ans[i]+mod)*iwo[i]%mod;
    }
    int main(){
    	Pro(N-11);
    	for (int T=iut();T;--T)
    	    print(ans[iut()]),putchar(10);
    	return 0;
    }
    
  • 相关阅读:
    C# List<T>中Select List Distinct()去重复
    Spring.Net 简单入门学习
    [ASP.NET MVC]:
    打车题
    Vue------发布订阅模式实现
    Vue----数据响应原理
    小程序自定义导航栏_navigationStyle
    CleanWebpackPlugin最新版本使用问题
    js-事件函数调用简化
    用XHR简单封装一个axios
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/15515211.html
Copyright © 2011-2022 走看看