POJ 1015 Jury Compromise (动态规划)

dp[i][j]代表选了i个人,D(J)-P(J)的值为j的状态下,D(J)+P(J)的最大和。

 

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <algorithm>



using namespace std;



const int MAXN = 810;



int n, m;

int dp[24][MAXN];

int path[24][MAXN];

int P[210], D[210];

int sub[210], sum[210];

int maxval, fix;

int ans[210];



bool IfHave( int i, int j, int k )

{

    while ( i > 0 )

    {

        if ( path[i][j] == k ) return true;

        j -= sub[ path[i][j] ];

        --i;

    }

    return false;

}



void DP()

{

    memset( dp, -1, sizeof(dp) );

    dp[0][0+fix] = 0;

    for ( int i = 1; i <= m; ++i )

        for ( int j = -fix; j <= fix; ++j )

        {

            if ( dp[i - 1][j + fix] >= 0 )

            {

                for ( int k = 1; k <= n; ++k )

                {

                    int newdp = dp[i - 1][ j+fix ]+sum[k];

                    int &curdp = dp[i][ j+fix+sub[k] ];

                    if ( !IfHave( i-1, j+fix, k) && newdp > curdp )

                    {

                        path[i][j+fix+sub[k]] = k;

                        curdp = newdp;

                    }

                }

            }

        }



    return;

}



void getPath( int i, int j )

{

    int cnt = 0;

    while ( i > 0 )

    {

        ans[cnt++] = path[i][j];

        j -= sub[ path[i][j] ];

        --i;

    }

    return;

}



int main()

{

    int cas = 0;

    while ( scanf( "%d%d", &n, &m ) == 2 && (n || m) )

    {

        for ( int i = 1; i <= n; ++i )

        {

            scanf( "%d%d", &P[i], &D[i] );

            sub[i] = P[i] - D[i];

            sum[i] = P[i] + D[i];

        }



        fix = 20 * m;

        maxval = 2 * fix;



        DP();



        int anssub, anssum;

        for ( int i = 0; i <= fix; ++i )

        if ( dp[m][fix-i] >= 0 || dp[m][fix+i] >= 0 )

        {

            if ( dp[m][fix-i] > dp[m][fix+i] )

            {

                anssub = fix-i;

                anssum = dp[m][fix-i];

            }

            else

            {

                anssub = fix+i;

                anssum = dp[m][fix+i];

            }

            break;

        }



        getPath( m, anssub );

        int sum1 = 0, sum2 = 0;

        for ( int i = 0; i < m; ++i )

        {

            sum1 += P[ ans[i] ];

            sum2 += D[ ans[i] ];

        }

        printf( "Jury #%d\n", ++cas );

        printf( "Best jury has value %d for prosecution and value %d for defence:\n", sum1, sum2 );

        sort( ans, ans + m );

        for ( int i = 0; i < m; ++i )

            printf( " %d", ans[i] );

        puts("\n");

    }

    return 0;

}

 

你可能感兴趣的:(Promise)