2018 徐州网络赛 B 博弈

定义 dp[ i ][ j ] 为进行第i轮选择,当前分数为 j 导致的最终结局。

dp[ i ][ j ] = 0 定义为 最终结局为badending

dp[ i ][ j ] = 1定义为 最终结局为normalending

dp[ i ][ j ] = 2定义为最终结局为goodending

#include 
using namespace std;
typedef long long LL;
typedef int lint;
const lint maxn = 1005;
lint dp[2][205];
lint a[maxn],b[maxn],c[maxn];
lint op1( lint i,lint val ){
    if( a[i] == 0 ) return -1;
    val += a[i];
    if( val < 0 ) return 0;
    if( val > 200 ) return 200;
    return val;
}
lint op2( lint i,lint val ){
    if( b[i] == 0 ) return -1;
    val -= b[i];
    if( val < 0 ) return 0;
    if( val > 200 ) return 200;
    return val;
}
lint op3( lint i,lint val ){
    if( !c[i] ) return -1;
    val -= 100;
    val *= -1;
    val += 100;
    if( val < 0 ) return 0;
    if( val > 200 ) return 200;
    return val;
}
lint n,m,k,l;
void solve( ){
    k += 100;l+= 100;
    for( lint i = 0;i <= 200;i++ ){
        if( i >= k ){
            dp[(n+1)%2][i] = 1;
        }else if( i <= l ){
            dp[(n+1)%2][i] = -1;
        }else dp[(n+1)%2][i] = 0;
    }
    bool flag;
    for( lint i = n;i >= 1;i-- ){
        if( i % 2 ) flag = true;
        else flag = false;
        for( lint j = 0;j <= 200;j++ ){
            lint s1 = op1( i,j );
            lint s2 = op2( i,j );
            lint s3 = op3( i,j );
            lint cnt0 = 0,cnt1 = 0,cnt2 = 0;
            if( s1 != -1 )
            if( dp[(i+1)%2][s1] == -1 ){
                cnt0++;
            }else if( dp[(i+1)%2][s1] == 0 ){
                cnt1++;
            }else cnt2++;
            if( s2 != -1 )
            if( dp[(i+1)%2][s2] == -1 ){
                cnt0++;
            }else if( dp[(i+1)%2][s2] == 0 ){
                cnt1++;
            }else cnt2++;
            if( s3 != -1 )
            if( dp[(i+1)%2][s3] == -1 ){
                cnt0++;
            }else if( dp[(i+1)%2][s3] == 0 ){
                cnt1++;
            }else cnt2++;
            if( flag ){
                if( cnt2 ){
                    dp[i%2][j] = 1;
                }else if( cnt1 ) {
                    dp[i%2][j] = 0;
                }else{
                    dp[i%2][j] = -1;
                }
            }else{
                if( cnt0 ){
                    dp[i%2][j] = -1;
                }else if( cnt1 ){
                    dp[i%2][j] = 0;
                }else{
                    dp[i%2][j] = 1;
                }
            }
        }
    }
}
int main(){
    while( ~scanf("%d%d%d%d",&n,&m,&k,&l)) {
        for (lint i = 1; i <= n; i++) {
            scanf("%d%d%d", &a[i], &b[i], &c[i]);
        }
        solve();
        m += 100;
        if (dp[1][m] == 1) {
            printf("Good Ending\n");
        } else if (dp[1][m] == -1) {
            printf("Bad Ending\n");
        } else {
            printf("Normal Ending\n");
        }
    }
    return 0;
}



 

你可能感兴趣的:(博弈)