666 RPG 計數dp入門

2021-09-11 18:00:39 字數 1553 閱讀 4127

lililalala正在玩一種有 n n個回合的回合制rpg遊戲,初始分數為0,第 i i個回合lililalala有如下兩種選擇。

a.將分數加上 ai ai

b.將分數 ×-1 ×-1

lililalala同樣也很討厭野獸數 666 666,但是他很卻喜歡數字 -666 -666。他想知道有多少種不同的方案使得 n n個回合後分數變為 -666 -666且在任何乙個回合之後分數都不為 666 666。

如果兩種方案有任何乙個回合選擇不同,就認為這兩種方案是不同的。

答案請對 108+7 108+7取模。

輸入包含兩行。

第一行乙個整數 n(1≤n≤300) n(1≤n≤300)。

第二行 n n個整數 a1a2a3...an(-666≤ a1a2a3...an≤666) a1a2a3...an(-666≤ a1a2a3...an≤666)。

輸出一行乙個整數--符合條件的不同方案數。
示例1

複製

3

-333 -333 -333

複製

1
僅一種符合條件的方案

第一回合選擇將分數 ×−1 ×−1。分數為 0 0

第二回合選擇將分數加上 -333 -333。分數為 -333 -333

第三回合選擇將分數加上 -333 -333。分數為 -666 -666

示例2複製

3

333 333 333

複製

0
示例3

複製

13

518 -643 -503 424 -76 -18 547 26 51 -647 -457 -5 329

複製

2
透過這道題讓我學會了如何處理小於零做陣列下標的情況。這題和上次訓練賽的a題是一致的,都是計數dp,將數作為陣列下標當成狀態。

如何處理小於零呢?

dp[i][j]代表第i個回合後分數為j的方案數

統統加上乙個非常大的數n,n就是代表0.n-666就是-666,n+666就是狀態666,然後dp一下就可以了。稍微滾動陣列優化一下節約空間。如何從6變成-6?也就是n+6->n-6;直接2*n-(n+6)=n-6;是不是感覺很妙。

#includeusing namespace std;

typedef long long ll;

const int n=300*666;

const int maxn=300*2*666+10,mod=1e8+7;

int a[305],cur,n;

ll dp[2][maxn],ans;

int main()

} dp[cur][n+666]=0;

if(i==n) ans=(ans+dp[cur][n-666]);

} cout<}

666RPG 計數dp簡單題

lililalala正在玩一種有 n n個回合的回合制rpg遊戲,初始分數為0,第 i i個回合lililalala有如下兩種選擇。a.將分數加上 ai ai b.將分數 1 1 lililalala同樣也很討厭野獸數 666 666,但是他很卻喜歡數字 666 666。他想知道有多少種不同的方案使...

計數DP,牛客練習賽41B題 666RPG

傳送門 lililalala正在玩一種有 n個回合的回合制rpg遊戲,初始分數為0,第 i i個回合lililalala有如下兩種選擇。a.將分數加上 ai ai b.將分數 1 1lililalala同樣也很討厭野獸數 666 但是他很卻喜歡數字 666 他想知道有多少種不同的方案使得n個回合後分...

牛客練習賽41 B 666RPG(計數dp)

思路 我們可以用 則可以得狀態轉移方程為 但是 include using namespace std define ll long long const int n 1e6 7 const int base 301 666 const int mod 1e8 7 int a 305 ll dp 2...