【DP】一道递推题。。。

Bob想要构造一张由n个节点构成的图。构造的过程由两步组成:首先Bob会取出n个孤立的点,并把它们从1到n编号,然后对每个节点用一种颜色染色,Bob一共可以使用K种不同的颜色。接下来Bob会在这张图中加入一些有向边,对于每一个编号范围在[2,n]的节点i,Bob有可能选择一个节点j满足j < i并且节点i与j的颜色不同,然后加入一条从i到j的有向边,对于节点i,Bob也有可能不加任何的有向边。现在你需要回答Bob有可能构造出多少种不同的图。

输入:

第一行包含三个整数n,K。

输出:

输出一个整数占一行,表示对应的答案模10^9 + 7。

样例输入:

3 2

样例输出:

24

(所有的24种可能情况如下)

数据范围:

对于20%的数据,1 <= n <= 5,1 <= K <= 2。

对于100%的数据,1 <= n <= 10^6,1 <= K <= 10^6。

  看到题被吓尿了,感觉根本没法做,写了个暴搜,结果全错+T了。。。

  这个题比较考思维,其实要往递推方向想。我们假设dp[i]表示有i个点时所能够画出来的所有组合,那么我们来分析一下是结果是如何递推的。

  dp[i]无非由两部分组成,一部分是不连线的,一部分是连线的,对于不连线的,很简单,只需要dp[i-1]*k就行了,无需多说。

  那么连线的部分怎么办呢?我们可以连向前i-1个点,但是我们并不知道它们的具体颜色,但是我们只要保证连着的两个颜色不一样即可,那么对于第i个点往前连的时候,它能连的颜色只有(k-1)种,然后分步原理,再乘上i-1的组合总数就行了,所以连线的部分转移方程是(i-1)*(k-1)*dp[i-1]。所以总的状态转移方程是dp[i]=dp[i-1]*k+(i-1)*(k-1)*dp[i-1]。。。不仔细想真想不出来啊。。。

  那么代码如下:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cstdlib>
 6 using namespace std;
 7 const long long MOD=1000000007;
 8 const int maxn=1000000+10;
 9 void init()
10 {
11     freopen("B.in","r",stdin);
12     freopen("B.out","w",stdout);
13     int size = 256 << 20; // 256MB
14     char *p = (char*)malloc(size) + size;
15     __asm__("movl %0, %%esp\n" :: "r"(p));
16 }
17 long long n,k;
18 long long dp[maxn];//i个节点,k种颜色,所有可能的组合总数
19 void read()
20 {
21     cin>>n>>k;
22 }
23 void work()
24 {
25     dp[0]=1;//一个节点都没有,是一种组合
26     for(long long i=1;i<=n;i++)
27     {
28         dp[i]=(k*dp[i-1]%MOD+((i-1)*(k-1))%MOD*dp[i-1]%MOD)%MOD;//递推方法:对于当前的dp[i],如果不连线,那么就有k种组合如果连线,那么有i-1个点可以连,但是要保证颜色不同,所以有k-1种颜色可以连,然后分步原理乘上i-1的组合总数
29     }
30     printf("%I64d",dp[n]);
31 }
32 int main()
33 {
34     init();
35     read();
36     work();
37     return 0;
38 }
时间: 2024-12-26 20:49:24

【DP】一道递推题。。。的相关文章

一堆递推题

目录 一堆递推题 P1367[训练题]爬楼梯[2] 描述 輸入 輸出 輸入範例 1 輸出範例 1 提示 思路 铺瓷砖 描述 輸入 輸出 輸入範例 1 輸出範例 1 思路 城市路径 描述 輸入 輸出 輸入範例 1 輸出範例 1 提示 思路 彩带 描述 輸入 輸出 輸入範例 1 輸出範例 1 提示 思路 斐波那契前N项和 描述 輸入 輸出 輸入範例 1 輸出範例 1 提示 思路 偶数个3 描述 輸入 輸出 輸入範例 1 輸出範例 1 思路 回文拆分 描述 輸入 輸出 輸入範例 1 輸出範例 1 思路

一道简单的递推题(快速幂+矩阵乘法优化+滚动数组)

问题 F: 一道简单的递推题 时间限制: 1 Sec  内存限制: 128 MB提交: 546  解决: 48[提交][状态][讨论版] 题目描述 存在如下递推式: F(n+1)=A1*F(n)+A2*F(n-1)+...+An*F(1) 求第K项的值对1000000007取模的结果 输入 单组测试数据 第一行输入两个整数 n , k (1<=n<=100,n<k<=10000000000) 第二行输入 n 个整数 F(1)   F(2)   ...   F(n) 第三行输入 n

hdu 1267 下沙的沙子有几粒?(二维递推题)

题意:就是给你m个H和n个D,然后从左开始数H的累积个数总是不比D的累计数少的排列有多少种举一个测试案例吧:3个H和1个D总共有3种排列,依次是:H D H H,H H D H,H H  H D三种排列,亲~意思应该懂了吧?!呵呵... 思路:递推公式为:a[m][n]=a[m-1][n]+a[m][n-1];然后当n=0的时候无论m取何值都是1,递推公式怎么推来的呢?我现在说下我的思路吧!假设3个H和2个D是由2个H和2个D还有3个H一个D推来的,2个H和2个D总共有H D H D,H H D

[ACM] hdu 3853 LOOPS (概率DP,递推)

LOOPS Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl). Homura wants to help her friend Madoka save the world. But because of the plot of the Boss Incubator, she is trapped in a labyrinth called LOOPS. The planform of the

timus 1225 flags 基础DP 简单递推

1225. Flags Time limit: 1.0 secondMemory limit: 64 MB On the Day of the Flag of Russia a shop-owner decided to decorate the show-window of his shop with textile stripes of white, blue and red colors. He wants to satisfy the following conditions: Stri

[sdut]2879计数dp……或者递推

第五届省赛C:colourful cupcakes N=60. 天真如我,居然在考虑搜索的算法/(ㄒoㄒ)/~~三叉树……3^60=10^24+……不计算考虑复杂度都是耍流氓>_< 再算了一下,感觉O(N^4)可以试试,60^4=10^8+……但是毕竟最差的情况嘛>_<,再看一下题解果然是4重循环的……计数……dp……(想到之前坚信的搜索不禁(*/ω\*)) 中间看到了一个三次动规六个方程的算法. 做麻烦了. 学长思路好快. #include<iostream> #in

HDU 3899 树形DP||树上递推

JLUCPC 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3899 Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1375    Accepted Submission(s): 413 Problem Description Dr. Skywind and Dr. Walkonclo

UESTC 2016 Summer Training #2 Div.2 A dp、递推、多阶段问题

A - A Time Limit:336MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu Submit Status Practice SPOJ AMR11A Description Thanks a lot for helping Harry Potter in finding the Sorcerer's Stone of Immortality in October. Did we not tell you that

UVa 825【简单dp,递推】

UVa 825 题意:给定一个网格图(街道图),其中有一些交叉路口点不能走.问从西北角走到东南角最短走法有多少种.(好像没看到给数据范围...) 简单的递推吧,当然也就是最简单的动归了.显然最短路长度就是row+col.求种数就从开始往后推. 由于第一行第一列也有可能是障碍点,所以初始化时要注意这一点,或者干脆就只初始化f[0][1]=1.i.j都从1开始递推到更方便.还有题目输入输出比较坑.输入我用的是sstream和stream,方便很多,要不还要按照字符串输入再手动转化成数字.输出让每组隔