【题】【矩阵乘法】NKOJ 3711 摆花
2016-07-20 21:08
344 查看
NKOJ 3711 摆花
时间限制 : - MS 空间限制 : 65536 KB
评测说明 : 时限1000ms
问题描述
艺术馆门前将摆出许多花,一共有n个位置排成一排,每个位置可以摆花也可以不摆花。有些花如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看了。假定每种花数量无限,求摆花的方案数。
输入格式
输入共有1+m行:
第一行有两个用空格隔开的正整数n、m,m表示花的种类数。
接下来的m行,每行有m个字符1或0,若第i行第j列为1,则表示第i种花和第j种花不能排在相邻的位置,输入保证对称。(提示:同一种花可能不能排在相邻位置)。
输出格式
输出只有一个整数,为方案数(这个数字可能很大,请输出方案数除以1000000007的余数)
样例输入 1
2 2
0 1
1 0
样例输出 1
7
样例输入 2
3 3
0 0 0
0 1 0
0 0 1
样例输出 2
50
提示
样例说明
七种方案为(空,空)、(空,1)、(1、空)、(2、空)、(空、2)、(1,1)、(2,2)
100%的数据,1<n≤1000000000,0<m≤100。
来源 CH Round#30
思路:
把空位看做一种花,且该种花可以和所有花摆放在一起
用二维数组a表示各种花之间的关系每多摆一个格子,就看做从一个点经过一条边到达下一个点,问题即转化为图论,因为各点都可以做起点或终点,所以最终的方案数为求幂和矩阵各个数之和
时间限制 : - MS 空间限制 : 65536 KB
评测说明 : 时限1000ms
问题描述
艺术馆门前将摆出许多花,一共有n个位置排成一排,每个位置可以摆花也可以不摆花。有些花如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看了。假定每种花数量无限,求摆花的方案数。
输入格式
输入共有1+m行:
第一行有两个用空格隔开的正整数n、m,m表示花的种类数。
接下来的m行,每行有m个字符1或0,若第i行第j列为1,则表示第i种花和第j种花不能排在相邻的位置,输入保证对称。(提示:同一种花可能不能排在相邻位置)。
输出格式
输出只有一个整数,为方案数(这个数字可能很大,请输出方案数除以1000000007的余数)
样例输入 1
2 2
0 1
1 0
样例输出 1
7
样例输入 2
3 3
0 0 0
0 1 0
0 0 1
样例输出 2
50
提示
样例说明
七种方案为(空,空)、(空,1)、(1、空)、(2、空)、(空、2)、(1,1)、(2,2)
100%的数据,1<n≤1000000000,0<m≤100。
来源 CH Round#30
思路:
把空位看做一种花,且该种花可以和所有花摆放在一起
用二维数组a表示各种花之间的关系每多摆一个格子,就看做从一个点经过一条边到达下一个点,问题即转化为图论,因为各点都可以做起点或终点,所以最终的方案数为求幂和矩阵各个数之和
#include<cstdio> #include<iostream> #include<cstring> using namespace std; #define ll long long const int p=1000000007; const int need=102; typedef int int_[need][need]; int_ a,ans,ans0,c; int n,m; void matrix_multi(int_ a,int_ b) { memset(c,0,sizeof(c)); for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) for(int k=1;k<=m;k++) c[i][j]=((ll)a[i][k]*b[k][j]%p+c[i][j])%p; memcpy(a,c,sizeof(c)); } void matrix_power(int b) { memcpy(ans,ans0,sizeof(ans0)); while(b) { if(b&1) matrix_multi(ans,a); b>>=1; matrix_multi(a,a); } } int main() { scanf("%d%d",&n,&m); for(int i=1,k;i<=m;i++) { ans0[i][i]=1; for(int j=1;j<=m;j++) { scanf("%d",&k); a[i][j]=1-k; } } m++; for(int i=1;i<=m;i++) a[m][i]=a[i][m]=1; ans0[m][m]=1; matrix_power(n-1); int cnt=0; for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) cnt=(ans[i][j]+cnt)%p; printf("%d",cnt); }
相关文章推荐
- 这几天的自学总结汇总
- 【Codeforces666B】【World Tour】【最短路】
- 字符串最后一个单词的长度
- 关于java 中的继承问题
- BZOJ 3685 普通van Emde Boas树
- CentOS7代理设置
- 求最大网络流(最小割)总结
- 面试题45:圆圈中最后剩下的数字
- [置顶] 安卓中滑动事件的传递机制及dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent的调用
- OGR示例:写shp,求面与面的交和差操作
- CodeIgniter框架将数据库查询结果导出为.csv或.cvs或excel文档
- IOS警告:Property access result unused - getters should not be used for side effects
- 【幻化万千戏红尘】qianfengDay08-java基础学习:修饰符、重写、继承、抽象、递归、final
- 求平均成绩 hd 2023
- DataGridView如何快速导出Excel
- codeforces水题100道 第二十三题 Codeforces Beta Round #77 (Div. 2 Only) A. Football (strings)
- Android 仿联系人字母索引
- Windows批处理(cmd/bat)常用命令小结
- socket是什么意思
- 《React-Native系列》5、RN实现弹出选择界面与动画效果