51Nod 1293 - 球與切換器(DP)
阿新 • • 發佈:2018-11-08
【題目描述】
【思路】
經過該切換器的球的總量是k,發現如果是該位置的值是1,那麼會有(k+1)/2的球像右去,剩下的球向下去。如果該位置的值是-1,那麼會有(k+1)/2的球像下去,剩下的球向右去。最後求右下角的位置球向下的數量。
設 表示經過位置 並向下走的球數量, 表示經過位置 並向右走的球的數量,然後就是噁心的狀態轉移了,還要注意1和-1的翻轉
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1005;
int n,m;
int g[maxn][maxn];
ll dp[maxn][maxn][2],k;
int main(){
//freopen("in.txt","r",stdin);
scanf("%d%d%lld",&m,&n,&k);
for(int i=0;i<n;++i) for(int j=0;j<m;++j) scanf("%d",&g[i][j]);
if(g[0][0]==1){
dp[0][0][0]=k/2;
dp[0][0][1]=(k+1)/2;
}
else if(g[0][0]==-1){
dp[0][0][0]=(k+1)/2;
dp[0][0][1]=k/2;
}
else dp[0][0][0]=k;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(i+1<n){
if(g[i+1][j]==1){
dp[i+1][j][0]+=dp[i][j][0]/2;
dp[i+1][j][1]+=(dp[i][j][0]+1)/2;
}
else if(g[i+1][j]==-1){
dp[i+1][j][0]+=(dp[i][j][0]+1)/2;
dp[i+1][j][1]+=dp[i][j][0]/2;
}
else{
dp[i+1][j][0]+=dp[i][j][0];
}
if(dp[i][j][0]&1) g[i+1][j]=-g[i+1][j];//奇數個球經過,這個位置的數字會翻轉
}
if(j+1<m){
if(g[i][j+1]==1){
dp[i][j+1][0]+=dp[i][j][1]/2;
dp[i][j+1][1]+=(dp[i][j][1]+1)/2;
}
else if(g[i][j+1]==-1){
dp[i][j+1][0]+=(dp[i][j][1]+1)/2;
dp[i][j+1][1]+=dp[i][j][1]/2;
}
else{
dp[i][j+1][1]+=dp[i][j][1];
}
if(dp[i][j][1]&1) g[i][j+1]=-g[i][j+1];//翻轉
}
}
}
/*puts("");
for(int i=0;i<n;++i){
for(int j=0;j<m;++j) printf("%d%c",dp[i][j][0],j+1==m?'\n':' ');
puts("");
}
puts("");
puts("");
for(int i=0;i<n;++i){
for(int j=0;j<m;++j) printf("%d%c",dp[i][j][1],j+1==m?'\n':' ');
puts("");
}
puts("");*/
printf("%lld\n",dp[n-1][m-1][0]);
return 0;
}