[HDU个人排位赛二 1006] Hmz 的女装 【DP】

来源:互联网 发布:酷友网络 编辑:程序博客网 时间:2024/04/28 13:57

Hmz 的女装

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 210    Accepted Submission(s): 104


Problem Description
Hmz为了女装,想给自己做一个长度为n的花环。现在有k种花可以选取,且花环上相邻花的种类不能相同。
Hmz想知道,如果他要求第l朵花和第r朵花颜色相同,做花环的方案数是多少。这个答案可能会很大,你只要输出答案对10^9+7取模的结果即可。
 

Input
第一行三个整数n,m,k(1≤n≤100000,1≤m≤100000,1≤k≤100000)
接下来m行,每行两个整数l,r,表示要求第l朵花和第r朵花颜色相同。保证l≠r且 |(r-l) mod n| ≠1.
 

Output
输出m行。对于每一个询问输出一个整数,表示做花环的方案数对10^9+7取模的结果。
 

Sample Input
8 3 21 42 61 38 3 31 42 61 3
 

Sample Output
02260108132

思路:

花环长度为n,一共有k种颜色,其中l和r的颜色相同,以l和r为边界,把花环分成两个线段,并且两条线段都不包括l和r端点。
用dp[m]表示长度为m的花环涂色方案的数目,dp[n]表示另一条长度为n的花环涂色方案的数目,l和r为 一特定颜色color,一共有
k种颜色,故花环的涂色方案数共有dp[m]*dp[n]*k种。
又由于一维的dp没有办法进行递推,故改成二维数组,dp[i][0]表示第i个与端点的颜色不同,dp[i][1]表示第i个与端点的颜色相同。
则可推出dp[i][0]=dp[i-1][0]*(k-2)+dp[i-1][1] *(k-1);dp[i][1]=dp[i-1][0];



#include <cstdio>#include <math.h>#include <cstring>#include <algorithm>using namespace std;const int MOD = 1e9 + 7;int n,m,k,l,r;long long dp[100005][2];//dp[i][0]表示第i个与端点处的color不同,dp[i][1]表示与端点处的color相同 int main(){while(~scanf("%d%d%d",&n,&m,&k)){dp[1][0] = k-1; dp[1][1] = 0;for(int i = 2; i <= n; i ++){dp[i][0] = (dp[i - 1][0] * (k-2) % MOD + dp[i-1][1] * (k-1) % MOD) % MOD;dp[i][1] = dp[i - 1][0];}while(m --){scanf("%d%d",&l,&r);if(l > r)swap(l,r);int len1 = r - l - 1, len2 = n - (r - l + 1);printf("%lld\n",dp[len1][0] * dp[len2][0] % MOD * k % MOD);}}return 0;}