阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有 N ( N ≤ 100 ) N(N \le 100) N(N≤100) 堆金币,第 i i i 堆金币的总重量和总价值分别是 m i , v i ( 1 ≤ m i , v i ≤ 100 ) m_i,v_i(1\le m_i,v_i \le 100) mi,vi(1≤mi,vi≤100)。阿里巴巴有一个承重量为 T ( T ≤ 1000 ) T(T \le 1000) T(T≤1000) 的背包,但并不一定有办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里巴巴最多可以拿走多少价值的金币?
第一行两个整数 N , T N,T N,T。
接下来 N N N 行,每行两个整数 m i , v i m_i,v_i mi,vi。
一个实数表示答案,输出两位小数
4 50
10 60
20 100
30 120
15 45
240.00
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
float N = sc.nextFloat();
float T = sc.nextFloat();
int i;
float m[] = new float[1000];
float v[] = new float[1000];
float x[] = new float[1000];
for (i = 0; i < N; i++)
{
m[i] = sc.nextFloat();
v[i] = sc.nextFloat();
}
System.out.println(String.format("%.2f", knapsack(T, m, v, x)));
}
public static float knapsack(float T, float m[], float v[], float x[]){
int n;
n = m.length;
int i, j;
float temp1, temp2;
float opt = 0;
for (i = 0; i < n; i++)
{
for (j = i + 1; j < n; j++)
{
if ((v[i] / m[i]) < (v[j] / m[j]))
{
temp1 = m[i];
m[i] = m[j];
m[j] = temp1;
temp2 = v[i];
v[i] = v[j];
v[j] = temp2;
}
}
}
for ( i = 0; i < n; i++)
{
x[i] = 0;
}
for (j = 0; j < n; j++)
{
if (m[j] > T)break;
x[j] = 1;
opt = opt + v[j];
T = T - m[j];
}
if (j本题可以使用背包问题的贪心算法实现,最重要的就是掌握代码中定义的knapsack函数,相当于一个模板,可以在其它题目中套用。
int n;
n = m.length;
int i, j;
float temp1, temp2;
float opt = 0;
for (i = 0; i < n; i++)
{
for (j = i + 1; j < n; j++)
{
if ((v[i] / m[i]) < (v[j] / m[j]))
{
temp1 = m[i];
m[i] = m[j];
m[j] = temp1;
temp2 = v[i];
v[i] = v[j];
v[j] = temp2;
}
}
}
for ( i = 0; i < n; i++)
{
x[i] = 0;
}
for (j = 0; j < n; j++)
{
if (m[j] > T)break;
x[j] = 1;
opt = opt + v[j];
T = T - m[j];//T此时表示背包剩余容量
}
if (jreturn opt;