zoukankan      html  css  js  c++  java
  • 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
    ", ++cas );
            printf( "Best jury has value %d for prosecution and value %d for defence:
    ", sum1, sum2 );
            sort( ans, ans + m );
            for ( int i = 0; i < m; ++i )
                printf( " %d", ans[i] );
            puts("
    ");
        }
        return 0;
    }
  • 相关阅读:
    MoveWindow() SetWindowPos()的区别与联系
    SEO搜索引擎优化基础
    Windows核心编程小结1
    STL学习笔记8 -- 函数对象
    Java关于反射
    多线程处理慢sql查询小笔记~
    前端小菜鸡使用Vue+Element笔记(二)
    前端小菜鸡使用Vue+Element笔记(一)
    Hive/hbase/sqoop的基本使用教程~
    Hive/Hbase/Sqoop的安装教程
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3451095.html
Copyright © 2011-2022 走看看