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. php 连接redis查询数据

    class Layoutdemo{ function index(){ $db = new Db(); $id=390; $layout_json = array(); if($info = $db- ...

  2. php性能优化--opcache

    一.OPcache是什么? OPcache通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能, 存储预编译字节码的好处就是 省去了每次加载和解析 PHP 脚本的开销. PHP 5 ...

  3. 给你的WP应用加上帮助文档

    背景 这算是Windows Phone编程回顾续篇, 接着给大家聊WP开发经验. 在开发了数个WP应用并发布后, 陆续收到很多反馈邮件, 其中接近一半的邮件是在问"某某功能有没有?" ...

  4. 创建、编译、执行 java程序

    java源文件(.java)——Java字节码文件(.class)——在java虚拟机上执行 其他语言很多是编译后执行,所以无法跨平台

  5. 转 Js 跨域CORS报错 Response for preflight has invalid HTTP status code 405

    转自:http://www.cnblogs.com/SilenceTom/p/6697484.html 调用接口遇到Response for preflight has invalid HTTP st ...

  6. SVM之对偶问题

    SVM之问题形式化 >>>SVM之对偶问题 SVM之核函数 SVM之解决线性不可分 写在SVM之前——凸优化与对偶问题 前一篇SVM之问题形式化中将最大间隔分类器形式化为以下优化问题 ...

  7. 图解linux安装tomcat(附常用命令)

    本例使用的是centos6.5版本,具体内容如下 一.首先到官方下载tomcat服务 http://tomcat.apache.org/download-70.cgi 二.将tomcat上传至linu ...

  8. 第61天:json遍历和封装运动框架(多个属性)

    一.json 遍历  for in  关键字  for ( 变量 in  对象)  { 执行语句;  } 例如: var json = {width:200,height:300,left:50}co ...

  9. OBJ文件

    OBJ文件是Alias|Wavefront公司为它的一套基于工作站的3D建模和动画软件"Advanced Visualizer"开发的一种标准3D模型文件格式,很适合用于3D软件模 ...

  10. iOS-开发中的时间处理

    做App避免不了要和时间打交道,关于时间的处理,里面有不少门道,远不是一行API调用,获取当前系统时间这么简单.我们需要了解与时间相关的各种API之间的差别,再因场景而异去设计相应的机制. 时间的形式 ...