标签:数学基础
In Summer 2011, the ZJU-ICPC Team has a n-days training schedule. ZJU-ICPC Team has been divided into 4 Group: Akiba, BiliBili, CIA, Double(Group A, B, C, D). There is a group in charge of the training problems on each day. As the ICPC Team manager, you have to decide which team is in charge of the problems on each day. But there are something you should rememeber:
1. No team is able to provide problems on two adjacent days.
2. There are m days in the Summer 2011 that which group is in charge of the problems have been decided. (e.g. Akiba provides problems on day 1, BiliBili provides problems on day 6. And these
can not be changed)
How many ways are there to arrange the schedule? Output the answer modulo 1000000007.
There are multiple test cases(less than 50). Each case contains two integers
n, m (1 ≤ n ≤ 10000000, 0 ≤ m ≤ 10), which indicate the number of days in Summer 2011 and the number of days that have been decided.
Following m lines. Each line contains one integer ai and one upper letter
Ch (‘A‘ ≤ Ch ≤ ‘D‘), indicate that on day ai (1 ≤
ai ≤ n), group Ch is in charge of the problems. We guarantee that all
ai are distinct. There is a blank line after each input case.
For each case, output a single line containing the answer, the number of the ways to arrange the schedule modulo 1000000007.
3 2 1 A 3 C 2 1 1 D
2 3
Case 1: 2 ways: ABC, ADC. Case 2: 3 ways: DA, DB, DC.
思路:这道题不太难,递推公式即可,但是代码实现得细心。好像递推公式也有多种,我的递推思路如下:
dp[i][0]:由第1个人安排第i天的任务,dp[i][1]:由第2个人安排第i天的任务,dp[i][2]:由第3个人安排第i天的任务,dp[i][3]:由第4个人安排第i天任务;
当扫描到第i天的时候,第i天的情况分为两种
(1):第i天安排已经固定了,那么由于同一个人不能在相邻两天出题,假设这一天是由A来安排,
那么dp[i][0]=dp[i-1][1]+dp[i][2]+dp[i-1][3]; dp[i][1]=dp[i][2]=dp[i][3]=0;
(2): 第i天安排没有固定,也就是安排第i天任务的人可以是A,B,C,D中的任何一个,同理也可由第i-1天推到第i天,得出递推公式dp[i][j]=dp[i-1][k1]+dp[i-1][k2]+dp[i-1][k3];
如果没有m的限制,直接矩阵快速幂即可,现在就因为m的存在,要分段快速幂;
注意细节;#include <iostream> #include <stdio.h> #include <string> #include <string.h> #include <algorithm> const int MOD=1000000007; using namespace std; typedef long long ll; int n,m; ll in[8]; // 矩阵运算 struct matrix { ll f[5][5]; }; matrix mul(matrix a,matrix b) { matrix c; memset(c.f,0,sizeof(c.f)); for(int i=0;i<4;i++) for(int j=0;j<4;j++) for(int k=0;k<4;k++) { c.f[i][j]+=(a.f[i][k]*b.f[k][j])%MOD; c.f[i][j]%=MOD; } return c; } matrix quick_mod(matrix a,int b) { matrix s; memset(s.f,0,sizeof(s.f)); for(int i=0;i<4;i++)s.f[i][i]=1; while(b) { if(b&1) s=mul(s,a); b/=2; a=mul(a,a); } return s; } matrix mat; //............ struct node { int day; char s[10]; }a[110]; bool cmp(node n1,node n2) { return n1.day<n2.day; } void init() { in[1]=in[2]=in[3]=in[4]=1; } int main() { mat.f[0][0]=0,mat.f[0][1]=1,mat.f[0][2]=1,mat.f[0][3]=1; mat.f[1][0]=1,mat.f[1][1]=0,mat.f[1][2]=1,mat.f[1][3]=1; mat.f[2][0]=1,mat.f[2][1]=1,mat.f[2][2]=0,mat.f[2][3]=1; mat.f[3][0]=1,mat.f[3][1]=1,mat.f[3][2]=1,mat.f[3][3]=0; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=m;i++)scanf("%d%s",&a[i].day,a[i].s); sort(a+1,a+1+m,cmp); init(); int cur=1; for(int i=1;i<=m;i++) { int d=a[i].day; if(d==1) { if(a[i].s[0]=='A') { in[1]=1; in[2]=in[3]=in[4]=0; } if(a[i].s[0]=='B') { in[2]=1; in[1]=in[3]=in[4]=0; } if(a[i].s[0]=='C') { in[3]=1; in[1]=in[2]=in[4]=0; } if(a[i].s[0]=='D') { in[4]=1; in[1]=in[2]=in[3]=0; } continue; } if(d-1-cur>0) { matrix tmp=mat; tmp=quick_mod(tmp,d-1-cur); ll a1=in[1]*tmp.f[0][0]%MOD+in[2]*tmp.f[0][1]%MOD+in[3]*tmp.f[0][2]%MOD+in[4]*tmp.f[0][3]%MOD; ll a2=in[1]*tmp.f[1][0]%MOD+in[2]*tmp.f[1][1]%MOD+in[3]*tmp.f[1][2]%MOD+in[4]*tmp.f[1][3]%MOD; ll a3=in[1]*tmp.f[2][0]%MOD+in[2]*tmp.f[2][1]%MOD+in[3]*tmp.f[2][2]%MOD+in[4]*tmp.f[2][3]%MOD; ll a4=in[1]*tmp.f[3][0]%MOD+in[2]*tmp.f[3][1]%MOD+in[3]*tmp.f[3][2]%MOD+in[4]*tmp.f[3][3]%MOD; in[1]=a1%MOD,in[2]=a2%MOD,in[3]=a3%MOD,in[4]=a4%MOD; } if(a[i].s[0]=='A') { in[1]=in[2]+in[3]+in[4]; //if(a[i].day=100)cout<<(in[2]+in[3]+in[4])%MOD<<endl; in[2]=in[3]=in[4]=0; } else if(a[i].s[0]=='B') { in[2]=in[1]+in[3]+in[4]; in[1]=in[3]=in[4]=0; } else if(a[i].s[0]=='C') { in[3]=in[1]+in[2]+in[4]; in[1]=in[2]=in[4]=0; } else { in[4]=in[1]+in[2]+in[3]; in[1]=in[2]=in[3]=0; } cur=a[i].day; } if(a[m].day!=n) { matrix tmp=mat; tmp=quick_mod(tmp,n-cur); ll a1=in[1]*tmp.f[0][0]%MOD+in[2]*tmp.f[0][1]%MOD+in[3]*tmp.f[0][2]%MOD+in[4]*tmp.f[0][3]%MOD; ll a2=in[1]*tmp.f[1][0]%MOD+in[2]*tmp.f[1][1]%MOD+in[3]*tmp.f[1][2]%MOD+in[4]*tmp.f[1][3]%MOD; ll a3=in[1]*tmp.f[2][0]%MOD+in[2]*tmp.f[2][1]%MOD+in[3]*tmp.f[2][2]%MOD+in[4]*tmp.f[2][3]%MOD; ll a4=in[1]*tmp.f[3][0]%MOD+in[2]*tmp.f[3][1]%MOD+in[3]*tmp.f[3][2]%MOD+in[4]*tmp.f[3][3]%MOD; in[1]=a1%MOD,in[2]=a2%MOD,in[3]=a3%MOD,in[4]=a4%MOD; } printf("%lld\n",(in[1]+in[2]+in[3]+in[4])%MOD); } return 0; }
标签:数学基础
原文地址:http://blog.csdn.net/liusuangeng/article/details/43317245