zoukankan      html  css  js  c++  java
  • ZOJ 3690 Choosing number(矩阵)

    Choosing number

    【题目链接】Choosing number

    【题目类型】矩阵

    &题解:

    这题就和已经dp极像了,所以找方程就很困难了.可以这样找:
    设f(n)是前n-1个人已经完成,第n个人选>k,g(n)是前n-1个人已经完成,第n个人选<=k.
    那么f(n)=f(n-1)*(m-k)+g(n-1)*(m-k) g(n)=f(n-1)*k+g(n-1)*(k-1)
    最后答案是f(n)+g(n) 所以这题难就难在想公式上

    【时间复杂度】(O(logn))

    &代码:

    #include <cstdio>
    #include <bitset>
    #include <iostream>
    #include <set>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <vector>
    using namespace std;
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int M= 1000000007;
    ll n,m,k;
    struct mat
    {
    	ll m[4][4];
    }A;
    mat Mul(mat a,mat b)
    {
    	mat c;
    	for(int i=0;i<2;i++){
    		for(int j=0;j<2;j++){
    			c.m[i][j]=0;
    			for(int k=0;k<2;k++){
    				c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%M;
    			}
    		}
    	}
    	return c;
    }
    mat bPow(mat a,ll z)
    {
    	mat un;
    	for(int i=0;i<2;i++)for(int j=0;j<2;j++)
    	un.m[i][j]=(i==j);
    	while(z){
    		if(z&1)
    			un=Mul(un,a);
    		a=Mul(a,a);
    		z>>=1;
    	}
    	return un;
    }
    int tb[4];
    void Init()
    {
    	tb[0]=m-k,tb[1]=k;
    	A.m[0][0]=A.m[0][1]=m-k;
    	A.m[1][0]=k,A.m[1][1]=k-1;
    }
    int main()
    {
    	freopen("E:1.txt","r",stdin);
    	while(cin>>n>>m>>k){
    		Init();
    		A=bPow(A,n-1);
    		ll ans=0;
    		for(int i=0;i<2;i++)
    		for(int j=0;j<2;j++){
    			ans=(ans+A.m[i][j]*tb[j])%M;
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Spring导出可以运行的jar包
    sed 多行处理详细总结
    Shell获取某目录下所有文件夹的名称
    linux 删除换行符
    linux 切分文件
    jdbctemplate 获取数据表结构的方法&注意事项
    linux 使用ifstat查看网络使用情况
    postgresql 函数获取多个字段的数字大小值
    vim 正则替换功能
    jstl 格式化
  • 原文地址:https://www.cnblogs.com/s1124yy/p/6667073.html
Copyright © 2011-2022 走看看