牛客小白月賽88-DE題解

ouhq發表於2024-03-13

D-我不是大富翁

題意:牛客小白月賽88-DE題解

做法:一開始是往貪心方面想,但是很明顯,貪不了。又因為走的步先後順序沒影響,可以用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的情況是相同處理的,不用特別處理。

相關文章