解题报告 之 POJ2782 Bin Packing
Description
- each bin contains at most 2 items,
- each item is packed in one of the q bins,
- the sum of the lengths of the items packed in a bin does not exceed l .
You are requested, given the integer values n , l , l1 , ..., ln , to compute the optimal number of bins q .
Input
Output
Sample Input
10 80 70 15 30 35 10 80 20 35 10 30
Sample Output
6
---------------------------------------------------------------------
话说这是这个博客上写的第一篇博文,其目的很单纯也很神圣,就是和别人约定好了一周不写完多少篇解题报告就要 请吃饭。。。所以我就开始写了,是不是被我的决心所折服了呢。
好了开始写了。
题目大意:有n个物品,体积分别为Li,每个箱子的容积都一样且为M。每个箱子最多装两个物品, 使得所装物品能够装得下。问最少用几个箱子把所有物品装完?
---------------------------------------------------------------
这个很明显是一个贪心,将物品体积从大到小排序。注意到,我们试图用重大的物品去匹配体积最小的物品,如果体积和小于M,那么这个箱子可以装两个;否则只能装大的那个。有的人会顾虑,是否需要找一个物品使得它与当前最大物品尽量填满箱子,以保证后面最优。这是没必要的,因为既然这个箱子可以与最大箱子共存,就一定可以和以后的任何箱子共存,所以大可以放在后面使用。
于是乎我们设置两个旗杆i和j分别指向第0个物品和第n-1个物品,数组w[i]表示第i个物品的体积,我们看w[i]+w[j]>=M?如果是就i++且j--(装两个物品),否则就只i++(装大的物品)。那么什么时候结束呢?当(i>j)结束,而非(i>=j),因为有可能出现最后i==j,那个物品仍然需要一个箱子。(有点类似快速排序的那种形式)。
最后我们就上代码了。
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <sstream>
#include <cstdio>
using namespace std;
int maxloc(int a[], int l, int r)
{
int key = l;
for ( int i = l; i <= r; i++)
{
if (a[i] >= a[key])
key = i;
}
return key;
}
struct pank
{
int loc;
int size;
bool operator <(const pank& rhs)const
{
return size < rhs.size;
}
};
void SWAP(int a[], int l, int r)
{
int i = l, j = r;
while (i < j)
{
int tem = a[i];
a[i] = a[j];
a[j] = tem;
i++; j--;
}
}
pank pan[40];
int Rank[40];
pank tem[40];
int main()
{
for (string strLine; getline(cin,strLine);)
{
cout << strLine << endl;
istringstream iss(strLine);
int n = 0;
while (iss >> pan[n].size)
{
pan[n].loc = n;
tem[n] = pan[n];
n++;
}
if (n == 0)
break;
sort(tem, tem + n);
int ans = 0;
for (int i = 0; i < n; i++)
Rank[tem[i].loc] = i;
for (int i = n-1; i >=0; i--)
{
int key = maxloc(Rank, 0, i);
if (key != i)
{
if (key != 0)
{
SWAP(Rank, 0, key);
cout << n - key << " ";
}
SWAP(Rank, 0, i);
cout << n- i << " ";
}
}
cout << 0 << endl;
}
return 0;
}
话说这个题似乎在UVA上数据有问题,但也不肯定,求大神真相一下。囧。。
最后祝愿我们嗑瓜子队伍可以越来越棒~~