Luogu P3758可樂(矩陣優化DP)

2022-05-01 01:21:12 字數 1470 閱讀 6460

題目鏈結

一開始想到這可能能用矩陣優化,但以為暴力就能卡過……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.第...