大假期第一次測試
今天算是返校第一天,進行了一次測試,分數少的可憐,也不知道該說些什麼。總感覺題目有點思路,程式碼就是寫不上來,很難受。有的就是思路錯了,T3不知道我咋想的,我居然當揹包問題做了。
還是看題吧:
T1太噁心了,我真的不知道該說什麼了
題目描述
下面數列的第 n 項:
f(0)=a0, f(1)=a1, f(2)=a2, f(n)=b*f(n-1)+c*f(n-2)+d*f(n-3)+e(n>=3),輸出f(n)的後18位,不足的用0在前補齊
樣例
樣例輸入
1 2 3 4 5 6 7 3
樣例輸出
000000000000000035
我就不寫程式碼了,太麻煩了。我把虎哥程式碼放這裡了https://www.cnblogs.com/kuangbiaopilihu/p/13305015.html(讀書人的事情怎麼能算偷呢——孔乙己)
T4也懶得寫,一起發了吧https://www.cnblogs.com/kuangbiaopilihu/p/13304530.html
T2
題目描述
菲菲和牛牛在一塊n行m列的棋盤上下棋,菲菲執黑棋先手,牛牛執白棋後手。
棋局開始時,棋盤上沒有任何棋子,兩人輪流在格子上落子,直到填滿棋盤時結束。落子的規則是:一個格子可以落子當且僅當這個格子內沒有棋子且這個格子的左側及上方的所有格子內都有棋子。
_Itachi聽說有不少學弟在省選現場AC了D1T1,解決了菲菲和牛牛的問題,但是_Itachi聽說有的人認為複雜度玄學,_Itachi並不想難為學弟學妹,他想為大家節約時間做剩下的題,所以將簡化版的D1T1帶給大家。
_Itachi也在一塊n行m列的棋盤上下棋,不幸的是_Itachi只有黑棋,不過幸好只有他一個人玩。現在,_Itachi想知道,一共有多少種可能的棋局(不考慮落子順序,只考慮棋子位置)。
_Itachi也不會為難學弟學妹們去寫高精度,所以只需要告訴_Itachi答案mod 998244353(一個質數)的結果。
樣例
樣例輸入1
1 1
樣例輸出1
2
樣例輸入2
2 3
樣例輸出2
10
樣例輸入3
10 10
樣例輸出3
184756
沒有圖也不好說明白,大家自己可以拿紙畫一下,斜過來就是一個楊暉三角了。虎哥說學長也講了另一個思路,用C(m+n,n)這個組合數%998244353。
需要用到逆元(不知道的去查逆元的定義)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 const int mod = 998244353; 5 long long qpow(int a, int b) { 6 long long ans = 1; 7 while(b) { 8 if(b&1) ans = (ans*a) %mod; 9 a=a*a%mod; 10 b>>=1; 11 } 12 return ans%mod; 13 } 14 long long solve(int a, int b) { 15 long long ans = 1; 16 for(int i = 1; i <= b; i++) ans *= (a-i+1), ans %= mod; 17 for(int i = 1; i <= b; i++) { 18 ans *= qpow(i,mod - 2); ans %= mod; 19 } 20 return ans % mod; 21 } 22 signed main() { 23 int x, y; cin>>x>>y; 24 cout << solve(x+y,min(x,y)); 25 return 0; 26 }View Code
T3就比較簡單了
題目描述
小明過生日的時候,爸爸送給他一副烏龜棋當作禮物。
烏龜棋的棋盤是一行N個格子,每個格子上一個分數(非負整數)。棋盤第1格是唯一的起點,第N格是終點,遊戲要求玩家控制一個烏龜棋子從起點出發走到終點。 ……
1 2 3 4 5……N
烏龜棋中M張爬行卡片,分成4種不同的型別(M張卡片中不一定包含所有4種類型的卡片,見樣例),每種型別的卡片上分別標有1、2、3、4四個數字之一,表示使用這種卡片後,烏龜棋子將向前爬行相應的格子數。遊戲中,玩家每次需要從所有的爬行卡片中選擇一張之前沒有使用過的爬行卡片,控制烏龜棋子前進相應的格子數,每張卡片只能使用一次。
遊戲中,烏龜棋子自動獲得起點格子的分數,並且在後續的爬行中每到達一個格子,就得到該格子相應的分數。玩家最終遊戲得分就是烏龜棋子從起點到終點過程中到過的所有格子的分數總和。
很明顯,用不同的爬行卡片使用順序會使得最終遊戲的得分不同,小明想要找到一種卡片使用順序使得最終遊戲得分最多。
現在,告訴你棋盤上每個格子的分數和所有的爬行卡片,你能告訴小明,他最多能得到多少分嗎?
樣例
樣例輸入1
9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1
樣例輸出1
73
樣例1解釋
小明使用爬行卡片順序為1,1,3,1,2,得到的分數為6+10+14+8+18+17=73。注意,由於起點是1,所以自動獲得第1格的分數6。
樣例輸入2
13 8
4 96 10 64 55 13 94 53 5 24 89 8 30
1 1 1 1 1 2 4 1
樣例輸出2
455
此題是NOIP2010提高組的題,很明顯一眼就是動規題,我也看出來了,但我用揹包做的,結果WA了,其實硬說這個題和揹包有關就是用到了揹包思想,因為資料範圍極小,直接四維陣列動規
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=350+10; 4 int a[maxn],d[45][45][45][45],b[5]; 5 int main(){ 6 int n,m; 7 scanf("%d%d",&n,&m); 8 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 9 for(int i=1,p;i<=m;i++){scanf("%d",&p);b[p]++;} 10 d[0][0][0][0]=a[1]; 11 for(int i=0;i<=b[1];i++) 12 for(int j=0;j<=b[2];j++) 13 for(int k=0;k<=b[3];k++) 14 for(int l=0;l<=b[4];l++){ 15 int num=a[1+i+2*j+3*k+4*l]; 16 if(i) d[i][j][k][l]=max(d[i][j][k][l],d[i-1][j][k][l]+num); 17 if(j) d[i][j][k][l]=max(d[i][j][k][l],d[i][j-1][k][l]+num); 18 if(k) d[i][j][k][l]=max(d[i][j][k][l],d[i][j][k-1][l]+num); 19 if(l) d[i][j][k][l]=max(d[i][j][k][l],d[i][j][k][l-1]+num); 20 } 21 printf("%d\n",d[b[1]][b[2]][b[3]][b[4]]); 22 return 0; 23 }View Code