【POJ1015】Jury compromise 多个费用的背包

这是一道比较综合的动态规划问题。

首先,根据题目中的从N个人中选出M个人,并且要使得某个目标函数最优,可以想到是背包问题,且因为要取出M个人,人数也应该作为背包体积的一个维度。

其次,要求输出路径,因此不能进行滚动数组优化(优化后无法记录状态转移途径)。

再次观察要求最优的函数,是一个相减取绝对值的函数,因此,可能出现负数,因此要给零点加一个偏移量。

状态的选取:\(dp[i][j][k]\)表示前 i (阶段)个物品中选取 j 个,且目标函数值为 k 时,和函数的最大值是多少。

代码如下:

#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <memory.h>
#define cls(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=201;
const int maxm=21;
const int maxdiff=801;

int n,m,kase,d[maxn],p[maxn],mid,ans_p,ans_d;
int dp[maxn][maxm][maxdiff],path[maxn][maxm][maxdiff];
std::vector<int> v;

void init(){
    cls(dp,0xcf);cls(path,0);
    v.clear();
    ans_p=ans_d=0;
}

void read_and_parse(){
    mid=m*20;//偏移量选取
    for(int i=1;i<=n;i++)
        scanf("%d%d",&p[i],&d[i]);
    for(int i=0;i<=n;i++)
        dp[i][0][mid]=0;
}

void print(int i,int j,int k){//路径处理
    if(!j)return;
    int idx=path[i][j][k];
    print(idx-1,j-1,k-(p[idx]-d[idx]));
    ans_d+=d[idx],ans_p+=p[idx];
    v.push_back(idx);
}

void solve(){
    for(int i=1;i<=n;i++){
        int cost=p[i]-d[i],val=p[i]+d[i];
        for(int j=1;j<=m;j++)
            for(int k=0;k<=mid<<1;k++){
                dp[i][j][k]=dp[i-1][j][k];
                path[i][j][k]=path[i-1][j][k];
                if(k-cost>=0&&dp[i][j][k]<dp[i-1][j-1][k-cost]+val){
                    dp[i][j][k]=dp[i-1][j-1][k-cost]+val;
                    path[i][j][k]=i;
                }
            }
    }
    int i,idx;
    for(i=0;i<=mid;i++)
        if(dp[n][m][mid-i]>=0||dp[n][m][mid+i]>=0)
            break;
    idx=(dp[n][m][mid-i]>dp[n][m][mid+i])?mid-i:mid+i;//比较和函数的大小

    print(n,m,idx);
    printf("Jury #%d\n", ++kase);
    printf("Best jury has value %d for prosecution and value %d for defence:\n",ans_p,ans_d);
    for(i=0;i<v.size();i++)printf(" %d",v[i]);
    puts("\n");
}

int main(){
    while(scanf("%d%d",&n,&m)&&m+n){
        init();
        read_and_parse();
        solve();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/wzj-xhjbk/p/9810204.html

时间: 2024-10-12 07:29:35

【POJ1015】Jury compromise 多个费用的背包的相关文章

[POJ1015] Jury Compromise 题解

题目描述: In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of members of the general public. Every time a trial is set to begin, a jury has to be selected, which is done as follows. First, several people ar

[dp] poj 1015 Jury Compromise

题目链接: http://poj.org/problem?id=1015 Jury Compromise Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 24438   Accepted: 6352   Special Judge Description In Frobnia, a far-away country, the verdicts in court trials are determined by a jury

K - Jury Compromise POJ 1015 (动态规划 --难)

K - Jury Compromise Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1015 Description In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of members of the ge

[kuangbin 基础dp][POJ 1015] Jury Compromise(dp)

[kuangbin 基础dp][POJ 1015] Jury Compromise 题目 In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of members of the general public. Every time a trial is set to begin, a jury has to be selected, which is do

POJ 1015 / UVA 323 Jury Compromise(01背包,打印路径)

POJ1015?UVA323?参考文章 (博主看了几篇文章,但是都没有考虑到背包容量的越界问题,关于这个,会在代码里解释.顺便提一下,POj这题的数据是比较弱的,建议去UVA 323检测一下代码的正确性) 题目大意:给出$n$对数,从中选出$m$对数,使各对数的差累加和最小的情况下总和最大. ??设每对数的差值为$sub[i]$,和为$sum[i]$.要从中选出m个数,对于每个数来说,都有选与不选两种情况,所以能不能用背包来做呢?用背包的话还得确定容量.既然题目要求$sub$的总和最小的情况下$

POJ 1015 Jury Compromise 2个月后重做,其实这是背包题目

http://poj.org/problem?id=1015 题目大意:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团.选m人的办法是:控方和辩方会根据对候选人的喜欢程度,给所有候选人打分,分值从0到20.为了公平起见,法官选出陪审团的原则是:选出的m个人,必须满足辩方总分和控方总分的差的绝对值最小.如果有多种选择方案的辩方总分和控方总分的之差的绝对值相同,那么选辩控双方总分之和最大的方案

背包系列练习( hdu 2844 Coins &amp;&amp; hdu 2159 &amp;&amp; poj 1170 Shopping Offers &amp;&amp; hdu 3092 Least common multiple &amp;&amp; poj 1015 Jury Compromise)

作为一个oier,以及大学acm党背包是必不可少的一部分.好久没做背包类动规了.久违地练习下-.- dd__engi的背包九讲:http://love-oriented.com/pack/ 鸣谢http://blog.csdn.net/eagle_or_snail/article/details/50987044,这里有大部分比较有趣的dp练手题. hdu 2844 Coins 多重背包 就是一个10w的多重背包,每个物品的cost同时也作为value去做背包,我们求的是每个容量下的价值,所以没

POJ 1015 Jury Compromise(dp坑)

提议:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团.选m人的办法是:控方和辩方会根据对候选人的喜欢程度,给所有候选人打分,分值从0到20.为了公平起见,法官选出陪审团的原则是:选出的m个人,必须满足辩方总分和控方总分的差的绝对值最小.如果有多种选择方案的辩方总分和控方总分的之差的绝对值相同,那么选辩控双方总分之和最大的方案即可. 题解:开始想到的是二维01背包,因为评价差的总分值最大可能

基础DP中的二维费用的背包

二维费用的背包问题: 指对于每件物品,具有2种不用的费用,选择这件物品需要同时付出2种代价 对于每一种代价都有一个可付出的最大值(背包容量) 问怎么样选择物品可以得到最大的价值 设这2种代价分别为1,2 第i件物品所需的2种代价为a[i] , b[i] 2种代价可付出的最大值为U,V 物品价值为w[i] 费用增加了一维,则状态也增加一维 设f[u][v]表示前i件物品付出代价为u,v时的最大价值 则f[u][v]=max(f[u][v],f[u-a[i]][v-b[i]]+w[i]) 1.物品只