zoukankan      html  css  js  c++  java
  • Acwing-280-陪审团(背包dp?)

    链接:

    https://www.acwing.com/problem/content/282/

    题意:

    在一个遥远的国家,一名嫌疑犯是否有罪需要由陪审团来决定。

    陪审团是由法官从公民中挑选的。

    法官先随机挑选N个人(编号1,2…,N)作为陪审团的候选人,然后再从这N个人中按照下列方法选出M人组成陪审团。

    首先,参与诉讼的控方和辩方会给所有候选人打分,分值在0到20之间。

    第 i 个人的得分分别记为p[i]和d[i]。

    为了公平起见,法官选出的M个人必须满足:辩方总分D和控方总分P的差的绝对值|D-P|最小。

    如果选择方法不唯一,那么再从中选择辨控双方总分之和D+P最大的方案。

    求最终的陪审团获得的辩方总分D、控方总分P,以及陪审团人选的编号。

    思路:

    看不太懂题解..考虑二维背包, 选的人数第一维, 辩控差为第二维.

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    int Dp[30][1000];
    vector<int> Path[210][1000];
    int p[210], d[210], sub[210], add[210];
    int id[210];
    int n, m;
    
    int main()
    {
        int cnt = 0;
        while (~scanf("%d%d", &n, &m))
        {
            if (n == 0 || m == 0)
                break;
            memset(Dp, -1, sizeof(Dp));
            for (int i = 0;i < m;i++)
            {
                for (int j = 0;j < 1010;j++)
                    Path[i][j].clear();
            }
            for (int i = 1; i <= n; i++)
            {
                scanf("%d%d", &p[i], &d[i]);
                sub[i] = p[i] - d[i];
                add[i] = p[i] + d[i];
            }
            int fix = m * 20;
            Dp[0][fix] = 0;
            for (int i = 1;i <= n;i++)
            {
                for (int j = m-1;j >= 0;--j)
                {
                    for (int k = 0;k < 2*fix;k++)
                    {
                        if (Dp[j][k] >= 0 && Dp[j+1][k+sub[i]] <= Dp[j][k]+add[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 k;
            for (k = 0; k <= fix; k++)
            {
                if (Dp[m][fix - k] >= 0 || Dp[m][fix + k] >= 0)
                    break;
            }
            int div;
            if (Dp[m][fix - k] > Dp[m][fix + k])
                div = fix - k;
            else
                div = fix + k;
            printf("Jury #%d
    ", ++cnt);
            printf("Best jury has value %d for prosecution and value %d for defence:
    ", (div + Dp[m][div] - fix) / 2,
                   (Dp[m][div] - div + fix) / 2);
            for (int i = 0;i < m;i++)
                printf(" %d", Path[m][div][i]);
            puts("");puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    继续OI
    [WARNING]考前必读?!
    近些日的总结吧
    续上文
    又是一年NOIP然鹅我考的是高数(虽然我没打并且内容与NOIP无关)(手动滑稽)
    轮船问题(DP基础)
    NOIP2016报零记
    字符数组
    HA-0302 退役
    各种模板(part 2)
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11504094.html
Copyright © 2011-2022 走看看