Maybe you know the famous russian souvenir Russian Dolls. It looks like a set of nested wooden dolls.
A doll with a smaller size is placed inside a bigger one. Let's consider all dolls taken apart. Each
doll has an outer volume outi which is the volume it occupies in space and an inner volume ini | the
volume of the empty space inside the doll. You may assume that you can put one doll inside another
if the outer volume of the rst doll is strictly less than the inner volume of the second one. If two or
more dolls are inside another one they can't lie one near the other, they must be nested.
For each doll the cost of unit of empty space | costi is known. You must pay exactly costi for each
unit of empty space which directly belongs to the i-th doll (but not to ones inside it). You may arrange
the dolls the way you want as long as you are not contradicting the rules. The objective is to nd an
arrangement of nesting the dolls (not necessarily all of them) such that the overall cost you have to pay
is minimized.
Input
The input le contains several test cases, each of them as described below.
First line contains an integer N (1 N 1000) which is the number of dolls you have. The i-th
of the next N lines contains three integers outi, ini, costi (1 ini < outi 1000, 1 costi 1000),
which are the outer volume, inner volume and the empty space cost of the i-th doll.
Sample Output
For each test case, write to the output a single integer P which is the minimum possible cost you should
pay on a line by itself.
Sample Input
3
5 4 1
4 2 2
3 2 1
Sample Output
7
题意:n个玩偶,每个玩偶有三个值:(第i个)外体积out(i),内部空体积in(i),单位空空体积的花费为cost(i)。第j个玩偶能放在第i个玩偶内部必须满足条件:out(j)<in(i)。一个玩偶内部要放多个玩偶,必须通过嵌套的方式。也就是说一个玩偶的内部空间如果存在多个玩偶,那么这些玩偶一定是嵌套的,不会存在两个玩偶并列在一个玩偶内部。设第i个玩偶内部的玩偶是x,那么第i个玩偶的花费为cost(i)*(in(i)-out(x))。最后问总花费最小可以为多少?
题解:总花费的公式可以写成:sum(cost(i)*(in(i)-out( i ')) ,1<=i<=n )。out(i')为放在第i个玩偶内部的玩偶的体积,如果 i!=j ,那么i'!=j' 。
我们还可以把公式展开成这种形式:sum(cost(i)*in(i))-sum(cost(i)*in(i')) 。前面一部分为定值,实际上我们要让后面一部分sum(cost(i)*in(i'))最大。容易想到这是个带权匹配问题,可以用费用流解决,但是复杂度显然太高。对于第i个玩偶来说,我们要让cost(i)*in(i') 最大的话,一定是贪心找满足条件的最大的 in(i‘) ,设i'=x。但是目前只是让第i个玩偶的值最大,有可能存在一个玩偶j,x能放在j里面,并且cost(j)>cost(i),那么cost(j)*in(x)>cost(i)*in(x),把x放在j更优。所以若cost(i)是所有玩偶中最大的,那么前面的贪心策略就一定是正确的。
代码如下:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<list>
#include<queue>
#include<string.h>
#define nn 1100
#define inff 0x3fffffff
using namespace std;
typedef long long LL;
struct node
{
int out,in,cost;
}a[nn];
int n;
bool cmp(node x,node y)
{
if(x.cost==y.cost)
return x.in>y.in;
return x.cost>y.cost;
}
bool use[nn];
int main()
{
int i,j;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&a[i].out,&a[i].in,&a[i].cost);
}
sort(a+1,a+n+1,cmp);
memset(use,false,sizeof(use));
int ans=0;
for(i=1;i<=n;i++)
{
int ix=0;
int id=-1;
for(j=1;j<=n;j++)
{
if(!use[j]&&a[j].out<a[i].in)
{
if(a[j].out>ix)
{
id=j;
ix=a[j].out;
}
}
}
if(id!=-1)
use[id]=true;
ans+=a[i].cost*(a[i].in-ix);
}
printf("%d\n",ans);
}
return 0;
}