您的位置:首页 > 其它

背包问题(物品可分解)--贪心算法

2016-03-22 20:40 281 查看


题目来自南阳理工OJ


背包问题

时间限制:3000 ms | 内存限制:65535 KB
难度:3

描述现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w<=10);如果给你一个背包它能容纳的重量为m(10<=m<=20),你所要做的就是把物品装到背包里,使背包里的物品的价值总和最大。

输入第一行输入一个正整数n(1<=n<=5),表示有n组测试数据;

随后有n测试数据,每组测试数据的第一行有两个正整数s,m(1<=s<=10);s表示有s个物品。接下来的s行每行有两个正整数v,w。
输出
输出每组测试数据中背包内的物品的价值和,每次输出占一行。

#include <iostream>

using namespace std;

#define MAX 12

int v[MAX]; //物品单位重量价值

int w[MAX]; //物品总重量

int v_arr[MAX]; //物品单位重量价值排序(物品名称)

void Get ( int s )

{

for ( int i = 0; i < s; i++ )

{

cin >> v[i] >> w[i];

}

}

void Arrange ( int s ) //对单位价值大小排序(记录的是脚标)

{

int record;

int v_arrange[MAX]; //物品单位重量价值排序

int i, j;

int max;

for ( i = 0; i < s; i++ )

{

v_arrange[i] = v[i]; //拷贝,为了不破坏原有数组

}

for ( i = 0; i < s; i++ ) //每次完整地搜索一遍数组,找到最大的

{

record = 0;

max = v_arrange[0];

for ( j = 1; j < s; j++ ) //j=1开始

{

if ( max < v_arrange[j] ) //和每次的最大值比较

{

max = v_arrange[j];

record = j;

}

}

v_arrange[record] = 0; //已找到的标记0,下次不再搜索

v_arr[i] = record; //记录脚标

}

}

int count_total_weight ( int s )

{

int total_weight = 0;

for ( int i = 0; i < s; i++ )

{

total_weight += w[i];

}

return total_weight;

}

int main()

{

int n; //n为测试数据组数

cin >> n;

while ( n-- )

{

int s, m; //s为物品数量,m为背包容量

cin >> s >> m;

int value = 0;

int i;

Get ( s );

if ( count_total_weight ( s ) <= m )

{

for ( i = 0; i < s; i++ )

{

value += v[i] * w[i];

}

}

else

{

i = 0;

Arrange ( s );

while ( m )

{

if ( m <= w[v_arr[i]] )

{

value += v[v_arr[i]] * m;

m = 0;

}

else

{

value += v[v_arr[i]] * w[v_arr[i]];

m = m - w[v_arr[i]];

}

i++;

}

}

cout << value << endl;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: