The only survival

http://acm.hdu.edu.cn/showproblem.php?pid=4903

Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Problem Description
There is an old country and the king fell in love with a devil. The devil always ask the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.

Something bad actually happen. The devil makes this kingdom's people infected by a disease called lolicon. Lolicon will take away people's life in silence.

Although z*p is died, his friend, y*wan is not a lolicon. Y*wan is the only one in the country who is immune of lolicon, because he like the adult one so much.

As this country is going to hell, y*wan want to save this country from lolicon, so he starts his journey.

You heard about it and want to help y*wan, but y*wan questioned your IQ, and give you a question, so you should solve it to prove your IQ is high enough.

The problem is about counting. How many undirected graphs satisfied the following constraints?

1. This graph is a complete graph of size n.
2. Every edge has integer cost from 1 to L.
3. The cost of the shortest path from 1 to n is k.

Can you solve it?

output the answer modulo 10^9+7

 
Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains 3 integers n,k,L.

T<=5 n,k<=12,L<=10^9.

 
Output
For each test case, output the answer in one line.
 
Sample Input
2
3 3 3
4 4 4
 
Sample Output
8
668
 
题意:
有一张n个点的无向完全图,第i个点的编号是i,每条边的边权在1到L之间的正整数,问存在多少个图使得1到n的最短路是k。
k<=12,L<=10^9,n<=12.
 
不会啊不会啊,借鉴了   Claris  神犇: http://www.cnblogs.com/clrs97/p/5690267.html
考场上咋办?
审题:
1、无向、完全图(即每个点都要与其他点有连边),由此应该想到如果k>l,无解
2、n=1,无解,n=2,输出1
 
限制非常宽的搜索,为了好搜,要自己加限制
计数问题可以强制不下降搜索,结果再用排列组合累计
 
进一步分析,
本题要求是最短路,那么如果我们算出了每个点的最短路,利用乘法原理在L范围内累积即可
再加限制:限制每个点到1号点的最短路
 
所以
枚举每个点到1号点的最短路
考虑两个点之间的边
如果i和j到1号点的最短距离相等,那么i与j之间的连边就可以是任意值
否则,就要考虑在满足最短路限制、边长限制下,这条边的情况。
至于边长是多少,不关心,他们与到1号点的最短路无关(已经枚举限制了),只需计算方案数,推推式子
 
对本题认识就这些了。。。。。。
 
#include<cstdio>
#include<algorithm>
using namespace std;
int n,k,l,ans;
int d[],f[],C[][];
const int mod=1e9+;
void dfs(int now,int dis,bool ok,int sum)
//当前枚举哪个点,这个点到1的最短距离,是否满足第n个点到1的最远距离为k,当前方案数
{
if(now== && !dis) return;//dis初值为0,只有第一个点的距离为0
d[now]=dis; ok|=dis==k;
if(now>)//计算当前点和前面所有点之间连边的方案数
if(dis<=k)
{
f[]=; f[]=;
//f[i][0/1]:第now与1到i之间的边是否存在一条边使当前dis成立
for(int i=;i<now;i++)
if(d[i]==dis) //1到now的最短距离==1到i的最短距离 ,那么now和i之间的边可以为任意长度,第i个点对dis是否成立毫无影响
{
f[]=1ll*f[]*l%mod;
f[]=1ll*f[]*l%mod;
}
else
      // 要保证1到now的最短距离为dis,如果之前在1——i-1中,已经有一条边使dis成立,那么i与now之间的边长只需>=dis-d[i];如果1——i-1中不存在这么一条边,那么i与now之间的边=dis-d[i]
//如果1——i与now之间的边不能使dis成立,前i-1个已经考虑过了,最后一个i与now之间的边 要>dis-d[i]
{//设这条边边权为val
f[]=(1ll*f[]*(l-dis+d[i]+)%mod+f[])%mod; //d[i]+val>=dis ==> dis-d[i]<=val<=L ==> val有L-(dis-d[i])+1种选择
f[]=1ll*f[]*(l-dis+d[i])%mod; //d[i]+val>dis ==> dis-d[i]<val<=L ==> val有L-(dis-d[i])种选择
}
sum=1ll*sum*f[]%mod;
}
else for(int i=;i<now;i++) sum=1ll*sum*min(l,l-k+d[i])%mod;
//如果dis>k,那么1到n的最短路一定不经过now,now与其他点的边就无所谓了
if(now==n)
{
if(!ok) return;
int j;
//搜索的时候d按不上升搜索,所以搜索出的d还要分配给每个点,组合计算分配方案数
for(int tmp=n-,i=;i<=n;i=j)
// 除去1和n,还剩n-2个点待分配
{
for(j=i;d[i]==d[j] && j<=n;j++);
//相等的d的范围:i——j-1,所以相等的d的个数为j-i
//给tmp个点中的j-i个点分配d,方案数为C(tmp,j-i)
if(d[i]==k) i++;//如果当前d==k,那么包含了点n,需要减去,给i加1,相当于给j-i减1
sum=1ll*sum*C[tmp][j-i]%mod;
tmp-=j-i; //有j-i个点分配完了
}
ans=(ans+sum)%mod;
return;
}
for(;dis<=k+;dis++) dfs(now+,dis,ok,sum);
//边长>k且<l的边全部看为k+1
}
int main()
{
C[][]=;
for(int i=;i<=;i++)
{
C[i][]=;
for(int j=;j<=i;j++)
C[i][j]=(C[i-][j-]+C[i-][j])%mod;
}
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&k,&l);
if(k>l) { puts(""); continue; }
ans=;
dfs(,,,);
printf("%d\n",ans);
}
}
#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; typedef long long LL; const int mod=1e9+; int N,K,L; int C[][]; int d[];
int f[]; int ans; void dfs(int now,int dis,bool ok,int sum)
{
if(now== && !dis) return;
d[now]=dis;
ok|=dis==K;
if(now>)
if(dis<=K)
{
f[]=;
f[]=;
for(int i=;i<now;++i)
if(d[i]==dis)
{
f[]=(LL)f[]*L%mod;
f[]=(LL)f[]*L%mod;
}
else
{
f[]=(LL)f[]*(L-dis+d[i]+)%mod;
f[]+=f[];
f[]-=f[]>=mod ? mod : ;
f[]=(LL)f[]*(L-dis+d[i])%mod;
}
sum=(LL)sum*f[]%mod;
}
else
for(int i=;i<now;++i) sum=(LL)sum*min(L,L-K+d[i])%mod;
if(now==N)
{
if(!ok) return;
int j;
for(int tmp=N-,i=;i<=N;i=j+)
{
for(j=i;d[j]==d[i] && j<=N;++j);
j--;
int cnt=j-i+;
if(d[i]==K) cnt--;
sum=(LL)sum*C[tmp][cnt]%mod;
tmp-=cnt;
}
ans+=sum;
ans-=ans>=mod ? mod : ;
return;
}
for(;dis<=K+;++dis) dfs(now+,dis,ok,sum);
} int main()
{
C[][]=;
for(int i=;i<=;++i)
{
C[i][]=;
for(int j=;j<=i;++j)
{
C[i][j]=C[i-][j]+C[i-][j-];
C[i][j]-=C[i][j]>=mod ? mod : ;
}
}
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&N,&K,&L);
ans=;
if(K<=L) dfs(,,false,);
cout<<ans<<'\n';
}
}
 

hdu 4903 The only survival的更多相关文章

  1. HDU.4903.The only survival(组合 计数)

    题目链接 惊了 \(Description\) 给定\(n,k,L\),表示,有一张\(n\)个点的无向完全图,每条边的边权在\([1,L]\)之间.求有多少张无向完全图满足,\(1\)到\(n\)的 ...

  2. HDOJ 4903 The only survival

    Discription: There is an old country and the king fell in love with a devil. The devil always ask th ...

  3. HDU 4903 (模拟+贪心)

    Fighting the Landlords Problem Description Fighting the Landlords is a card game which has been a he ...

  4. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  6. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  7. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  8. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  9. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

随机推荐

  1. Ext JS 6学习文档-第4章-数据包

    Ext JS 6学习文档-第4章-数据包 数据包 本章探索 Ext JS 中处理数据可用的工具以及服务器和客户端之间的通信.在本章结束时将写一个调用 RESTful 服务的例子.下面是本章的内容: 模 ...

  2. HADOOP docker(十):hdfs 结构体系

    1.简介2.namenode和datanode3.The File System Namespace 文件系统命名空间4.Data Replication 数据复制5.Replica Placemen ...

  3. HDU 2489 Minimal Ratio Tree(暴力+最小生成树)(2008 Asia Regional Beijing)

    Description For a tree, which nodes and edges are all weighted, the ratio of it is calculated accord ...

  4. Thunder团队第六周 - Scrum会7

    Scrum会议7 小组名称:Thunder 项目名称:i阅app Scrum Master:杨梓瑞 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传 ...

  5. jconsole工具监控数据分析

    当Jconsole连接成功后,它从JMX获取信息,我们便可以在里面监控具体的内容.Jconsole能捕获到以下信息: 概述 - JVM概述和一些监控变量的信息 内存 - 内存的使用信息 线程 - 线程 ...

  6. phpcms 模型

  7. 解决XAMPP中,MYSQL因修改my.ini后,无法启动的问题

    论这世上谁最娇贵,不是每年只开七天的睡火莲,也不是瑞典的维多利亚公主,更不是一到冬天就自动关机的iPhone 6s, 这世上最娇贵的,非XAMPP中的mysql莫属,记得儿时的我,年少轻狂,当时因为m ...

  8. codeforces 981 C.Useful Decomposition

    C. Useful Decomposition time limit per test 1 second memory limit per test 256 megabytes input stand ...

  9. bzoj1143-祭祀

    题目 给出一个有向无环图,要在上面安放祭祀点.两个祭祀点必须不可达,求最多能安放多少个祭祀点. 分析 由于一条无法再延伸链上只能安放一个祭祀点,而我们要求的是最多能安放祭祀点的个数,所以要求的就是最长 ...

  10. 【bzoj4300】绝世好题 dp

    题目描述 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len). 输入 输入文件共2行. 第一行包括一个整数n. 第二行包括n个 ...