您的位置:首页 > 其它

2017杭电ACM集训队单人排位赛 - 2 -1006 Hmz 的女装

2017-07-06 14:07 417 查看
problem 1006

最近cf打多了,做什么都往找规律或者暴力贪心上想,其实这道题是一个很简单的dp。

题干:

Hmz为了女装,想给自己做一个长度为n的花环。现在有k种花可以选取,且花环上相邻花的种类不能相同。

Hmz想知道,如果他要求第l朵花和第r朵花颜色相同,做花环的方案数是多少。这个答案可能会很大,你只要输出答案对109+7取模的结果即可。

这样的话,我们只要把花环分成两段,对于每一段单独考虑。

设dp[i][2],i为花环的长度,dp[i][0]表示在i 位置上的花环和(l,r)上的颜色一样的个数,dp[i][1]表示在i 位置上的花环和(l,r)上的颜色不一样的个数;

设其中一段花环的长度为x,这样的话我们最后只要得到dp[x][1],就是这一段的种类数,最后把两段相乘,即dp[x][1]*dp[y][1],最后再乘上(l,r)上的种类数,就是最后的答案。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <bitset>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define pb(a) push_back(a)
#define fir first
#define se second
#define LL unsigned long long
typedef pair<int,int> pii;
typedef pair<LL,int> pli;
typedef pair<LL,LL> pll;
const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;
LL mod = 1e9+7;

LL dp[maxn][2];

int main() {
int n,m,k;
while(cin>>n>>m>>k) {
dp[0][0] = 0;
dp[0][1] = k-1;
for(int i = 1;i <= n;i++) {
dp[i][0] = dp[i-1][1];
dp[i][1] = (dp[i-1][0]*(k-1)%mod + dp[i-1][1]*(k-2)%mod)%mod;
}
for(int i = 1;i <= m;i++) {
int l,r;
scanf("%d%d",&l,&r);
if(l > r) swap(l,r);  //这里l可能大于r,坑
int d = r-l-1;
int d1 = n-2-d;
LL s = k;
LL ans = dp[d-1][1]*s%mod*dp[d1-1][1]%mod;
printf("%I64d\n",ans);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  杭电 acm dp