poj1015 01背包+输出路径

版权声明:转载请注明出处 https://blog.csdn.net/jay__bryant/article/details/82023753

题意:给定人数n(1<=n<=200),每个人有一个a, b。(0<=a<=b),从中选择m个人,使得|sigma(a)-sigma(b)|最小,若相等则sigma(a)+sigma(b)最大。求最优策略的sigma(a),sigma(b)和选择的人的编号

dp[i][j]:选择了i个人,|sigma(a)-sigma(b)|==j时sigma(a)+sigma(b)最大为dp[i][j]。
由于|sigma(a)-sigma(b)|可能有负值,且最大负值为-20*m,所以令0 -> -20*m, 20*m->0, 2*20*m->20*m。
在状态转移的时候更新路径即可。

#include <cstdio>
#include <vector>
#include <cstring>

using namespace std;
const int N = 210;
const int INF = 0x3f3f3f3f;
int dp[N][N<<2];
vector <int> path[N][N<<2];
int add[N],sub[N];
int n, m;

int main()
{
    int cas = 0;
    while(~scanf("%d %d", &n, &m) && (m+n))
    {
        for(int i = 1; i <= m; ++i)
            for(int j = 0; j < N; ++j)
                path[i][j].clear();
        for(int i = 1; i <= n; ++i)
        {
            int a, b;
            scanf("%d %d", &a, &b);
            add[i] = a+b;
            sub[i] = a-b;
        }
        memset(dp, -1, sizeof(dp));
        int zero = 20*m;
        dp[0][zero] = 0;
        for(int i = 1; i <= n; ++i)
            for(int j = m-1; j>=0; --j)
                for(int k = 2*zero; k>0 ; --k)
                    if(~dp[j][k] && (k+sub[i]>=0&&k+sub[i]<=2*zero))
                        if(dp[j][k]+add[i] > dp[j+1][k+sub[i]])
                        {
                            dp[j+1][k+sub[i]] = dp[j][k]+add[i];
                            path[j+1][k+sub[i]] = path[j][k];
                            path[j+1][k+sub[i]].push_back(i);
                        }
        int i = 0;
        while(dp[m][i+zero]==-1 && dp[m][-i+zero]==-1) ++i;
        int tmp = dp[m][i+zero]>dp[m][-i+zero]?i+zero:-i+zero;
        int ans1 = (dp[m][tmp]+(tmp-zero))/2;
        int ans2 = (dp[m][tmp]-(tmp-zero))/2;
        printf("Jury #%d\n", ++cas);
        printf("Best jury has value %d for prosecution and value %d for defence:\n", ans1, ans2);
        for(int i = 0; i < m; ++i)
            printf(" %d", path[m][tmp][i]);
        printf("\n\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jay__bryant/article/details/82023753