【小米oj】 海盗分赃

背包

#define mm(a) memset(a,0,sizeof(a));
#define max(x,y) (x)>(y)?(x):(y)
#define min(x,y) (x)<(y)?(x):(y)
#define Fopen freopen("1.in","r",stdin); freopen("m.out","w",stdout);
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,b,a) for(int i=(b);i>=(a);i--)
#include<bits/stdc++.h>
typedef long long ll;
#define PII pair<ll,ll>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=(int)2e5 + 5;
const ll mod=1e9+7;


string input,temp;
vector<int>v;
int n,dp[MAXN];
int main() {
    while (cin >> input) {
//    cin>>input;
        istringstream iss(input);
        v.clear();
        v.push_back(0);
        mm(dp);
        int all=0;
        while (getline(iss, temp, ',')) {
            int x=atoi(temp.c_str());
            v.push_back(x);
            all+=x;
        }
        if(all&1) {
            printf("false\n");
            return 0;
        }
        n=v.size()-1;
        dp[0]=1;
        for(int i=1; i<=n; i++) {
            for(int j=all/2; j>=v[i]; j--) {
                dp[j]=max(dp[j],dp[j-v[i]]);
            }
        }
        if(dp[all/2])printf("true\n");
        else printf("false\n");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/dogenya/p/10815601.html

### 关于东方博宜OJ平台上“海盗的财宝”题目解析 #### 题目描述 在一个遥远的小岛上,有N个海盗找到了一批宝藏。这批宝藏由M件不同的物品组成,每件物品都有自己的价值Vi和重量Wi。这些海盗希望尽可能公平地分配这些财富,使得每个人获得的价值总和相等或接近。 具体来说,给定一个整数数组`value[]`表示各个物品的价值以及另一个整数数组`weight[]`代表对应的重量,还有两个正整数N(海盗数量)和W(最大承重),目标是在不超过各自的最大承载能力的前提下,找到一种方案让每位海盗所携带物品的总价值之差最小化[^1]。 #### 解决思路 此问题可以被建模成一个多维背包问题的一个变种形式。为了简化处理过程并提高效率,这里采用动态规划的方法来解决这个问题: - 定义状态 `dp[i][j]` 表示前 i 种商品,在容量 j 的情况下能够达到的最大价值; - 初始化边界条件:当没有任何货物时 (`i=0`) 或者容器为空(`j=0`) ,此时能获取到的最大值自然为零; - 对于每一个新的项目 k (即第k类商品),遍历所有可能的状态组合(i,j), 更新 dp 数组中的元素;如果当前考虑加入新项目的剩余空间允许,则尝试更新该位置上的最优解。 最终通过比较不同分发方式下各成员间所得财物差距大小得出最佳策略[^2]。 ```cpp #include <iostream> using namespace std; const int MAX_N = 105; // 货物数目上限 int value[MAX_N], weight[MAX_N]; // 各项属性定义 double dp[2][MAX_N * 100 + 5]; void solve(int n, int m){ fill(dp[0], dp[2], -1); // 初始化DP表,-1标记未访问过的位置 dp[0][0]=0; for(int i=1;i<=n;++i){ memset(dp[i%2], -1 ,sizeof(double)*(m*100+1)); for(int w=0;w<=m*100;++w) if(dp[(i-1)%2][w]>=0){ dp[i%2][w]=max(dp[i%2][w], dp[(i-1)%2][w]); if(w+weight[i]<=m*100) dp[i%2][w+weight[i]]=max( dp[i%2][w+weight[i]], dp[(i-1)%2][w]+value[i] ); } } double min_diff=DBL_MAX,best_sum=-1; for(int sum=0;sum<=m*100 && best_sum<0;++sum) if(abs(sum-(m-sum))<min_diff&&dp[n%2][sum]>best_sum){ min_diff=abs(sum-(m-sum)); best_sum=sum; } } // 主函数部分省略... ``` 上述代码实现了基于二维滚动数组优化后的多维度背包算法框架,其中包含了如何计算每个状态下所能得到的最佳收益,并且最后还加入了对于结果的选择逻辑以满足题目要求——使各位参与者之间的差异尽可能小[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值