題目鏈結
一開始想到這可能能用矩陣優化,但以為暴力就能卡過……t成二十分
首先我們回顧一下我們的暴力轉移方程
用f[i][j][0/1]表示在i時刻,j點,1不**,0已**的方案數,那麼f[i][j][0]=f[i-1][j][0]+f[i-1][j][1],f[i][j][1]=f[i-1][j][1]+f[i-1][k][1](其中k表示與j相鄰的點)。
然後我們看f[i][j][1]=f[i-1][j][1]+f[i-1][k][1]這個式子
如果設定j和j相連,就化簡為f[i][j][1]=f[i-1][k][1]
然後就可以用矩陣乘法啦
考慮到f[i][j][0]的求法,發現這是乙個關於f[i-1][j][1]的和
而我們發現f[i-1][j][1]是一串矩陣等比數列
於是應用等比數列求和公式
#include#include#include
#include
#include
#define mod 2017inline
long
long
read()
while
(isdigit(ch))
return num*f;
}int
n,m;
struct
matrix
matrix
operator *(const matrix &a)
matrix
operator +(const matrix &a)
};matrix pow(matrix x,
intp)
return
ans;
}matrix sum(matrix x,
intp)
int q[300][300
];matrix start;
intans;
intmain()
for(int i=1;i<=n;++i) q[i][i]=1
;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j) start.s[i][j]=q[i][j];
int t=read();
matrix now; now=pow(start,t);
for(int i=1;i<=n;++i) ans=(ans+now.s[i][1])%mod;
matrix sum; sum=sum(start,t -1
);
for(int i=1;i<=n;++i) sum.s[i][i]=(sum.s[i][i]+1)%mod;
for(int i=1;i<=n;++i) ans=(ans+sum.s[i][1])%mod;
printf("%d
",ans);
return0;
}
375 猜數字大小 II
我們正在玩乙個猜數遊戲,遊戲規則如下 我從1到n之間選擇乙個數字,你來猜我選了哪個數字。每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。示例 n 10,我選擇了8.第一輪 你...
375 猜數字大小 II
我們正在玩乙個猜數遊戲,遊戲規則如下 我從1到n之間選擇乙個數字,你來猜我選了哪個數字。每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。示例 n 10,我選擇了8.第一輪 你...
375 猜數字大小 II
我們正在玩乙個猜數遊戲,遊戲規則如下 我從 1 到 n 之間選擇乙個數字,你來猜我選了哪個數字。每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。示例 n 10,我選擇了8.第...