D-我不是大富翁
題意:
做法:一開始是往貪心方面想,但是很明顯,貪不了。又因為走的步先後順序沒影響,可以用dp來寫。暴力也差不多。
值得注意的點是動力序列可以一邊讀入一邊處理,省了點空間。
如果dp[5005][5005]這樣開的話會MLE,實際上在dp的過程中,用到的只是i和i-1兩行,其餘都是多餘的。
所以可以這樣定義dp[2][5005]這樣可以避免MLE;
還有就是要特判n==1的情況。
//int dp[5005][5005]; //--MLE
int dp[2][5005]; //最佳化空間!!! wa--5 1 0
//dp[i][j]定義為,到了第i步,可以到達j哪些格子。
//暴力差不多--遍歷m步.每步遍歷n,看看可以到達哪些格子.看看最後一步是否可以到達1.
void solve(){ //D
int n,m,x;
cin>>n>>m;
if(n==1){ //特判!!
cout<<"YES";
return;
}
dp[0][1]=1;
for(int i=1;i<=m;i++){
cin>>x;
x%=n;
for(int j=1;j<=n;j++){
if(dp[(i+1)%2][j]){
dp[(i+1)%2][j]=0; //重置!!!否則下一步會再次進入
dp[i%2][(j+x)%n]=1;
dp[i%2][(j-x+n)%n]=1;
}
}
}
if(dp[m%2][1]) cout<<"YES";
else cout<<"NO";
}
在寫的時候加了個條件判斷x==0的情況,但是實際上x==0的情況是相同處理的,不用特別處理。