您的位置:首页 > 理论基础 > 计算机网络

Chinese Rings 2842 hdu (http://qzc.zgz.cn/Y-jiulianhuan3.htm 很流氓的网址)

2010-03-27 17:30 495 查看
]/* http://qzc.zgz.cn/Y-jiulianhuan3.htm 原来这是一个游戏
记从始点到前k个环在上用f(k)步,考虑怎么上这前k个环呢?可以先上前k-1个环,用f(k-1)步,
再下前k-2个环,用f(k-2)步。此时仅有第k-1个环在上,可以进行动作Q上k号环,用1步,
然后再上前k-2个环,用f(k-2)步。f(k)就是以上各个动作所需步数的和,
f(k)=f(k-1)+f(k-2)+1+f(k-2) =f(k-1)+2f(k-2)+1即   f(k) =f(k-1)+2f(k-2)+1
这是确定函数关系的一种方法,叫做递归方法,与大家熟知的数学归纳法的原理有相似之处。
如果知道了f(1),f(2)的值,由此可以计算出f(3),有了f(3),与f(2)一起又可以计算f(4),等等,
直到f(9),或者更一般的f(k)。当然,这必须先知道f(1),f(2)的值,这犹如数学归纳法里的归纳假设。
容易知道,f(1)=1,f(2)=2。所以由
f(k) =f(k-1)+2f(k-2)+1,f(1)=1,f(2)=2
*/
#include <iostream>
#include <cstdio>
using namespace std;
const int mod = 200907;
struct Mat
{
long long int num[3][3];
Mat()
{
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
num[i][j] = 0;
}
};
Mat mal(Mat a, Mat b)
{
Mat r;
for(int i = 0; i < 3; i++)
for(int k = 0; k < 3; k++)
{
if(a.num[i][k])
for(int j = 0; j < 3; j++)
{
if(b.num[k][j])
r.num[i][j] = (r.num[i][j] + a.num[i][k] * b.num[k][j]) % mod;
}
}
return r;
}
Mat mul(Mat a, Mat b, int n)
{
while(n)
{
if(n & 1)
{
b = mal(a, b);
n--;
}
else
{
a = mal(a, a);
n >>= 1;
}
}
return b;
}
int main()
{
int n;
while( cin >> n && n)
{
if(n == 1 || n == 2)
{
printf("%d/n", n);
continue;
}
Mat init, unit;
init.num[0][0] = 1;	init.num[0][1] = 2;	init.num[0][2] = 1;
init.num[1][0] = 1;
init.num[2][2] = 1;
unit.num[0][0] =2;	unit.num[1][0] = 1;	unit.num[2][0] = 1;
Mat ans = mul(init, unit, n - 2);
printf("%I64d/n", ans.num[0][0] % mod);
}
}
http://acm.hdu.edu.cn/showproblem.php?pid=2842

//递推公式 f
= f[n-1] + 2*f[n-2] +1        f[1] = 1 f[2] =2
#include<iostream>//2255440 2010-03-27 17:26:15 Accepted 2842 0MS 296K 1332 B C++ 悔惜晟
using namespace std;
const int mod = 200907;
 
 struct stu
 {
  long long int a[3][3]; 
 } df1, df2;
 
 stu mul(stu p, stu q)
 {
  int i, j, k;
  stu r;
  for(i = 0; i < 3; i++)
   for(j = 0; j < 3 ; j++)//一开始这里括号加错了,郁闷了好久
   {
    r.a[i][j] = 0;
    for( k = 0; k < 3; k++)
     r.a[i][j] += p.a[i][k]* q.a[k][j]; 
     if(r.a[i][j] >= mod)
     r.a[i][j] %= mod;  
   }
  return r;  
 }
 
 stu mal(int n)
 {
  stu p = df1;
  stu q = df2;
  while(n > 1)
  {
   if(n % 2 == 0)
   {
    q = mul(q, q);
    n /= 2;
   }
   else
   {
    p = mul(p , q);
    n--;
   }
  }
  return mul(p, q);
 }
int main()
{
 int n, s[4], i, j;
 long long sum;
 while(cin>>n && n != 0)//0的时候不执行
 {
  if(n == 1)
   cout<<"1"<<endl;
  else if(n == 2)
   cout<<"2"<<endl;
  else
  {
   n -= 2;
   for(i = 0 ;i < 3; i++)
     for(j =0 ; j <3 ;j++)
    if(i == j)
    df1.a[i][j] = 1;
    else
    df1.a[i][j] =0;
   
   df2.a[0][0] = 1;
   df2.a[0][1] = 2;
   df2.a[0][2] = 1;
   df2.a[1][0] = 1;
   df2.a[1][1] = 0;
   df2.a[1][2] = 0;
   df2.a[2][0] = 0;
   df2.a[2][1] = 0;//一开始矩阵写错了。纠结啊。。
   df2.a[2][2] = 1;//
   
   s[0] = 2;
   s[1] = 1;
   s[2] = 1;
   stu ans;
   ans = mal(n);
   sum = 0;
   for(i = 0 ; i < 3; i++)
    sum += (ans.a[0][i]*s[i])%mod;
    cout<<sum%mod<<endl;
  }
 }
 
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struct 游戏 2010 c