原文链接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. python学习第11天 迭代器

    函数的名称 闭包 迭代器 递归

  2. [转]ASCII码表及扩展ASCII码表,方便查阅

    ASCII码表可以看成由三部分组成: 第一部分:由00H到1FH共32个,一般用来通讯或作为控制之用.有些可以显示在屏幕上,有些则不能显示,但能看到其效果(如换行.退格).如下表: 第二部分:是由20 ...

  3. Python-多表关联 外键 级联

    分表为什么分表 多表关联多表关系 ****** 表之间的关系 为什么要分表 多对一 一个外键 多对多 一个中间表 两个外键 一对一 一个外键加一个唯一约束外键约束 ****** foreign key ...

  4. 自然语言处理之关键词提取TF-IDF

    统计每篇文章重要的词作为这篇文章的关键词,用tf-idf来实现.生产中有很多第三包可以调用,这里记录原理,顺便熟练python 1.公式 : 计算词频TF 考虑到文章有长短之分,为了便于不同文章的比较 ...

  5. C#实现向excel中插入行列,以及设置单元格合并居中效果

    插入空行: Microsoft.Office.Interop.Excel.Workbook xlsWorkbook; Microsoft.Office.Interop.Excel.Worksheet ...

  6. Oracle Vm VirtualBox 搭建 yum 环境

    配置本地yum库(用root用户操作) 创建挂载目录 #创建挂载目录 [root@oracle ~]# mkdir /mnt/cdrom # 查看挂载目录 [root@oracle ~]# ls /m ...

  7. Confluence 6 关于 Decorators

    Confluence 是使用开源的 SiteMesh 库构建的.一个 Web 页面的布局系统,这个布局系统能够在全站点中提供完整统一的界面和外观.SiteMesh 是通过 "decorato ...

  8. 1709: Fire or Retreat(zzuli)

    水题,哎,可是第一次是因为编译错了,vs不知咋了,无奈: 后面几次又因为类型用了int错了,痛苦: 题目描述 在与科技水平远胜于我们的外星人的战斗最后,我们能够用来对外星装甲造成伤害的武器只剩下了…… ...

  9. 字符串为空的比较 ==与equals() 区别(キ`゚Д゚´)!!基础很重要 !!!

    情况描述:我提交的代码,让老大审批了一次,讲真的,对于我来说受益匪浅,其中有一个印象很深的内容:一个字符串是否为空的判断,我以前敲代码一直都是这样写的,可是从来都没有意识到这个东西. 代码: if(s ...

  10. Laravel5使用QQ邮箱发送邮件配置

    在.env文件中设置如下MAIL_DRIVER=smtpMAIL_HOST=smtp.qq.comMAIL_PORT=465MAIL_USERNAME=00000000000@qq.comMAIL_P ...