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

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);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值