[矩阵乘法][动态规划]Arrange the Schedule
来源:互联网 发布:精准扶贫数据平台网址 编辑:程序博客网 时间:2024/05/29 03:02
Arrange the Schedule
64-bit integer IO format: %lld Java class name:Main
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 thesecan not be changed)
How many ways are there to arrange the schedule? Output the answer modulo 1000000007.
Input
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 letterCh ('A' ≤Ch ≤ 'D'), indicate that on day ai (1 ≤ai ≤ n), groupCh is in charge of the problems.We guarantee that allai are distinct.There is a blank line after each input case.
Output
For each case, output a single line containing the answer, the number of the ways to arrange the schedule modulo 1000000007.
Sample Input
3 21 A3 C2 11 D
Sample Output
23
Hint
Case 1:2 ways: ABC, ADC.Case 2:3 ways: DA, DB, DC.
Source
Author
一开始想到的是三维的方程。
f(i,j,k) = Σ {f(i-1,k,k2)*2 (j≠k2),f(i-1,k,k2)*3(j=k2)}
k的存在是明显的冗余(前后有相同)。这样的枚举是多余的。
直观上,我们对多种情况归为两类而变得简单,其实枚举量增加了不少。
其实状态只与上一位置有关。但是这样仍然会超时。
观察发现第一个方程是一个简单的递推,能够联想到矩阵乘法。但是如何处理后两个方程?
题目上可以看见,会用到后两个方程的位置,即开始就有字母的位置,是相当稀疏的。
而递推是连续的,因此我们大可分段计算,以预先有字母的位置为断点,把1~n断成多段。
这个矩阵,明显是存在的,因为该递推公式是多项式。
这个矩阵其实就是:
0,1,1,1
1,0,1,1
1,1,0,1
1,1,1,0
时间复杂度为O(mlgn),很快。
这个问题的初始状态的考虑有些麻烦,最好将1位置有无字母分开单独考虑,作为两个初始状态,这是因为从位置0推出1位置并不好实现。
#include <cstdio>#include <cstring>#include <algorithm>using std::sort;typedef long long ui;struct node{int p;int c;bool operator<(const node& n2)const{return p < n2.p;}};const ui MOD = 1000000007;void multi1(ui a[6][6],ui b[6][6],ui c[6][6]){ui tmp[6][6];memset(tmp,0,sizeof tmp);for (int i=1;i<=4;i++){for (int j=1;j<=4;j++){for (int k=1;k<=4;k++){tmp[i][j] = (tmp[i][j]+a[i][k]*b[k][j])%MOD;}}}for (int i=0;i<6;i++)for (int j=0;j<6;j++)c[i][j] = tmp[i][j];}void multi2(ui a[6][6],ui b[6],ui c[6]){ui tmp[6];memset(tmp,0,sizeof tmp);for (int i=1;i<=4;i++){for (int k=1;k<=4;k++){tmp[i] = (tmp[i]+a[i][k]*b[k])%MOD;}}for (int i=0;i<6;i++)c[i] = tmp[i];}node ex[20];const ui initial[6][6] = {{0,0,0,0,0,0},{0,1,0,0,0,0},{0,0,1,0,0,0},{0,0,0,1,0,0},{0,0,0,0,1,0},{0,0,0,0,0,0}};const ui matrix[6][6] = {{0,0,0,0,0,0},{0,0,1,1,1,0},{0,1,0,1,1,0},{0,1,1,0,1,0},{0,1,1,1,0,0},{0,0,0,0,0,0}};ui ma[6][6];ui mb[6];void quickpower(int k){ui ans[6][6];ui tmp[6][6];for (int i=0;i<6;i++)for (int j=0;j<6;j++){ans[i][j] = initial[i][j];tmp[i][j] = matrix[i][j];}while (k){if (k&1){multi1(ans,tmp,ans);}multi1(tmp,tmp,tmp);k >>= 1;}for (int i=0;i<6;i++)for (int j=0;j<6;j++)ma[i][j] = ans[i][j];}int n;int m;int main(){freopen("ats.in","r",stdin);freopen("ats.out","w",stdout);while (scanf("%d%d",&n,&m) == 2){mb[0] = mb[1] = mb[2] = mb[3] = mb[4] = mb[5] = 0;for (int i=1;i<=m;i++){scanf("%d",&ex[i].p);do{ex[i].c = getchar()-'A'+1;}while (ex[i].c>4 || ex[i].c<1);}m++;ex[m].p = n+1;ex[m].c = 5;sort(ex+1,ex+m+1);int i;if (ex[1].p == 1){mb[ex[1].c] = 1;i = 2;}else{mb[1] = mb[2] = mb[3] = mb[4] = 1;i = 1;ex[0].p = 1;}for (;i<=m;i++){quickpower(ex[i].p-ex[i-1].p-1);multi2(ma,mb,mb);int tmp = 0;for (int j=1;j<=4;j++){if (j != ex[i].c){tmp = (tmp+mb[j])%MOD;}}mb[1]=mb[2]=mb[3]=mb[4] = 0;mb[ex[i].c] = tmp;}printf("%lld\n",mb[5]);}return 0;}
- [矩阵乘法][动态规划]Arrange the Schedule
- zoj 3538 Arrange the Schedule[矩阵]
- ZOJ 3538 Arrange the Schedule 矩阵快速幂
- ZOJ 3538 Arrange the Schedule / 矩阵快速幂
- zoj 3538 Arrange the Schedule(矩阵快速幂)
- zoj 3538 Arrange the Schedule
- zoj 3538 Arrange the Schedule
- 动态规划 矩阵链乘法
- 动态规划 矩阵链乘法
- 动态规划----矩阵链乘法
- 动态规划 -- 矩阵链乘法
- 矩阵乘法(动态规划)
- 动态规划-矩阵链乘法
- 【动态规划】矩阵链乘法
- 动态规划-矩阵链乘法
- 动态规划-矩阵链乘法
- 动态规划--矩阵链乘法
- ZOJ HDU 3538 Arrange the Schedule
- UVa11541 - Decoding
- (转载)cocos2d-X学习之主要类介绍:CCDirector
- 《算法导论》习题解答 Chapter 22.1-5(求平方图)
- CF 7D: Palindrome Degree
- 避免代码注释的五大理由
- [矩阵乘法][动态规划]Arrange the Schedule
- 关于qsort的比较函数的不同写法对于大数据造成的错误
- sprintf()函数
- 修改Linux内核启动图片
- 如何成就一只懒散的团队?
- linux程序安装包----动态链接库的自动编译与安装
- java获取服务器一些信息的方法(服务器地址/相对路径/端口/项目名字)
- SSH依赖包介绍
- NGUI核心组件