【深基12.例1】部分背包问题——仔细检查数据类型!

题目描述

阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有 N(N100) 堆金币,第 i 堆金币的总重量和总价值分别是 mi,vi(1mi,vi100)。阿里巴巴有一个承重量为 T(T1000) 的背包,但并不一定有办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里巴巴最多可以拿走多少价值的金币?

输入格式

第一行两个整数 N,T

接下来 N 行,每行两个整数 mi,vi

输出格式

一个实数表示答案,输出两位小数

样例 #1

样例输入 #1

4 50
10 60
20 100
30 120
15 45

样例输出 #1

240.00

我的作答

#include <bits/stdc++.h>
using namespace std;
int main() {
int n,t;
cin >> n >> t;
int m[110],v[110];
double p[110];
for (int i=0;i<n;i++) {
cin >> m[i] >> v[i];
p[i] = (double) v[i] / m[i];
}
for (int i=0;i<n-1;i++) {
for (int j=0;j<n-i-1;j++) {
if (p[j] < p[j+1]) {
double temp1 = p[j];
p[j] = p[j+1];
p[j+1] = temp1;
int temp2 = m[j];
m[j] = m[j+1];
m[j+1] = temp2;
int temp3 = v[j];
v[j] = v[j+1];
v[j+1] = temp3;
}
}
}
int sum_m=0;
double sum_v=0.00;
for (int i=0;i<n;i++) {
if ((sum_m+m[i])<t) {
sum_v += v[i];
sum_m += m[i];
} else {
sum_v += (double)(t-sum_m) * v[i] / m[i];
sum_m = t;
break;
}
}
printf("%.2lf",sum_v);
return 0;
}

反思总结

首先是一个易错点:

double temp1 = p[j];
p[j] = p[j+1];
p[j+1] = temp1;

冒泡排序时,要注意temp1的数据类型正确;我在做本题时就因为这里导致出错。

然后是背包装满的循环问题:

for (int i=0;i<n;i++) {
if ((sum_m+m[i])<t) {
sum_v += v[i];
sum_m += m[i];
} else {
sum_v += (double)(t-sum_m) * v[i] / m[i];
sum_m = t;
break;
}
}

在装满背包之后,要break跳出循环。(本题不需要)

发布于   xiins  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示