原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1231.html

题目传送门 - 51Nod1231

题意

题解

  显然是一个竞赛图相关的题。

  我们首先证明一个结论:

    一个出度序列存在对应的 $n$ 个点的竞赛图的充分必要条件是:这个出度序列的所有元素之和为 $\cfrac{n(n-1)}{2}$ ,且 对于这个出度序列中任意 $k$ 个元素,满足他们的和 $\geq \cfrac{k(k-1)}{2}$ 。

  由于我懒得写证明(证明需要用构造法,自行百度),这个结论的证明略去。

  于是我们只需要保证最终的出度序列的总和为 $\cfrac{n(n-1)}{2}$ ,并且将其排序后,对于所有 $k \in [1,n]$ ,前 $k$ 个元素之和 $\geq \cfrac{k(k-1)}2$ 即可。

  我们按照数值从小到大填。

  我们令 $dp[i][j][k]$ 表示前 $i$ 个数,当前最后一个数为 $j-1$ ,前 $i$ 个数的总和为 $k$ 的方案总数。然后大力 DP 即可。

  dp 复杂度的上限是 $O(n^5)$ 的,但是由于有很多无用的状态,所以 20 组数据仍然可以跑过去。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=45,mod=1e9+7;
int T,n,a[N],C[N][N],dp[N][N][N*N],cnt[N],tot[N];
int calc(int x){
return x*(x-1)/2;
}
void add(int &x,int y){
x+=y;
if (x>=mod)
x-=mod;
}
int solve(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
memset(cnt,0,sizeof cnt);
for (int i=1;i<=n;i++)
if (a[i]>=0)
cnt[a[i]]++;
memset(tot,0,sizeof tot);
for (int i=n;i>=0;i--)
tot[i]=tot[i+1]+cnt[i];
memset(dp,0,sizeof dp);
dp[0][0][0]=1;
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
for (int k=0;k<=calc(n);k++){
int v=dp[i][j][k];
if (!v)
continue;
for (int t=0;i+t<=n-tot[j+1];t++){
int _k=k+t*j;
if (_k>calc(n)||calc(i+t)>_k)
break;
if (t<cnt[j])
continue;
add(dp[i+t][j+1][_k],1LL*v*C[n-i-tot[j]][t-cnt[j]]%mod);
}
}
int ans=0;
for (int i=0;i<=n;i++)
add(ans,dp[n][i][calc(n)]);
return ans;
}
int main(){
for (int i=0;i<N;i++)
C[i][0]=C[i][i]=1;
for (int i=1;i<N;i++)
for (int j=1;j<i;j++)
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
scanf("%d",&T);
while (T--)
printf("%d\n",solve());
return 0;
}
/*
dp[i][j][k]表示前 i 个数,最后一个数是 j , 所有数的总和为 k 的序列总数
dp[i+t][j+1][k+t*j]+=C[n-i][t]*dp[i][j][k]
j<n,i+t<=n
k+t*j<=n*(n-1)/2
forall t' in [0,t] , (i+t')*(i+t'-1)/2<=k+t*j
*/

  

51Nod1231 记分牌 动态规划的更多相关文章

  1. 增强学习(三)----- MDP的动态规划解法

    上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...

  2. 简单动态规划-LeetCode198

    题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...

  3. 动态规划 Dynamic Programming

    March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...

  4. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  5. C#动态规划查找两个字符串最大子串

     //动态规划查找两个字符串最大子串         public static string lcs(string word1, string word2)         {            ...

  6. C#递归、动态规划计算斐波那契数列

    //递归         public static long recurFib(int num)         {             if (num < 2)              ...

  7. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  8. 【体系结构】动态调度算法:记分牌算法和tomasulo算法

    记分牌和tomasulo算法 动态调度: 通过硬件在程序执行时重新安排代码的执行序列来减少竞争引起的流水线停顿时间 动态调度流水线具备以下功能: (1)允许按序取多条指令和发射多条指令----取指(I ...

  9. 【BZOJ1700】[Usaco2007 Jan]Problem Solving 解题 动态规划

    [BZOJ1700][Usaco2007 Jan]Problem Solving 解题 Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地 ...

随机推荐

  1. ueditor使用

    <html>    <head>        <meta charset="UTF-8">        <title></ ...

  2. input错误提示,点击提交,提示有未填项,屏幕滑到input未填项的位置

    function errorInfo(parm) { //获取文本框值 var $val = parm.val(); if ($val==""||undefined||null){ ...

  3. WPF窗体的生命周期

    和所有类一样,窗口也有生存期,在第一次实例化窗口时生存期开始,然后就可以显示.激活和停用窗口,直到最终关闭窗口. 1.显示窗体 构造函数 Show().ShowDialog()方法:Show()方法显 ...

  4. 在线HTTP POST/GET接口测试工具 - aTool在线工具

    百度搜索标题或直接访问网址如下 网址:http://www.atool.org/httptest.php 很好用的在线http get/post 测试工具

  5. 判断js数据类型的四种方法,以及各自的优缺点(转)

    转载地址:https://blog.csdn.net/lhjuejiang/article/details/79623973 数据类型分为基本类型和引用类型: 基本类型:String.Number.B ...

  6. JSP的内置对象及方法

    request表示HttpServletRequest 对象.它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie,header, 和session 数据的有用的方法.response 表 ...

  7. HttpListener通讯成功案例

    1.创建WindowsService,如下代码 using System;using System.Net;using System.Net.Sockets;using System.ServiceP ...

  8. iOS项目国际化详解

    现在的开发中难免会遇到项目国际化处理,下面把我理解到的国际化相关的知识点进行总结归纳 1 首先是对项目名称,系统性的文字进行名字化,比如程序名字 1,先给项目添加语言 2 添加InfoPlist.st ...

  9. ajax请求数据时什么时候用GET,什么时候用POST

    GET的目的就如同其名字一样是用于获取信息的.它旨在显示出页面上你要阅读的信息.浏览器会缓冲GET请求的执行结果,如果同样的GET请求再次发出,浏览器就会显示缓冲的结果而不是重新运行整个请求.重新请求 ...

  10. 阿里云服务器配置SSL证书成功开启Https(记录趟过的各种坑)

    环境: 阿里云云服务器    Windows Server 2008 标准版 SP2 中文版(趁1212优惠买的一年的水货配置) 阿里云购买的域名(已备案.已解析) 服务器:phpstudy:php5 ...