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...