Arthur has bought a beautiful big table into his new flat. When he came home, Arthur noticed that the new table is unstable.
In total the table Arthur bought has n legs, the length of the i-th leg is li.
Arthur decided to make the table stable and remove some legs. For each of them Arthur determined number di — the amount of energy that he spends to remove the i-th leg.
A table with k legs is assumed to be stable if there are more than half legs of the maximum length. For example, to make a table with 5 legs stable, you need to make sure it has at least three (out of these five) legs of the maximum length. Also, a table with one leg is always stable and a table with two legs is stable if and only if they have the same lengths.
Your task is to help Arthur and count the minimum number of energy units Arthur should spend on making the table stable.
The first line of the input contains integer n (1 ≤ n ≤ 105) — the initial number of legs in the table Arthur bought.
The second line of the input contains a sequence of n integers li (1 ≤ li ≤ 105), where li is equal to the length of the i-th leg of the table.
The third line of the input contains a sequence of n integers di (1 ≤ di ≤ 200), where di is the number of energy units that Arthur spends on removing the i-th leg off the table.
Print a single integer — the minimum number of energy units that Arthur needs to spend in order to make the table stable.
2 1 5 3 2
2
3 2 4 4 1 1 1
0
6 2 2 1 1 3 3 4 3 5 5 2 1
8
题目大意:
一个桌子有N条腿,每条腿的长度为li,去掉第i个腿用di花费。
一个桌子平稳的规定为:最长长度的腿的数量为num.总腿数为tot.需要满足num>tot/2.
思路:
我们首先按照腿长从小到大排序。
那么我们可以O(n)枚举留下来的桌腿最长的长度是多少。
那么对应假设我们当前枚举留下来的桌腿最长的长度是maxn.那么很明显,大于maxn长度的所有桌腿都要去掉。
那么我们这里可以维护一个前缀和sum【i】表示【1,i】长度区间内所有桌腿去掉的花费.
对应我们枚举留下来的桌腿最长的长度是maxn.其桌腿个数为x个,那么我们可以保留下来小于他长度的桌腿数量为x-1个.
那么我们需要维护小于这个maxn长度的最大价值的x-1个进行保留,其余进行删除。
此时观察到1<=di<=200,那么我们之前可以过程维护每个价值的桌腿都有多少个,那么我们可以从200向1枚举出来x-1个桌腿进行保留,其余的进行删除.
总时间复杂度O(200*n);
Ac代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
int len,val;
}a[100500];
int sum[100500];
int num[100500];
int have[250];
int cmp(node a,node b)
{
return a.len<b.len;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
memset(have,0,sizeof(have));
for(int i=0;i<n;i++)scanf("%d",&a[i].len),num[a[i].len]++;
for(int i=0;i<n;i++)scanf("%d",&a[i].val),sum[a[i].len]+=a[i].val;
sort(a,a+n,cmp);
for(int i=1;i<=100400;i++)sum[i]=sum[i-1]+sum[i];
int output=0x3f3f3f3f;
for(int i=0;i<n;i++)
{
int can_live=num[a[i].len]-1;
int tmp=sum[100400]-sum[a[i].len];
//printf("--%d %d %d\n",i,tmp,can_live);
for(int j=200;j>=1;j--)
{
if(have[j]>0)
{
if(can_live>=have[j])
{
can_live-=have[j];
}
else
{
tmp+=j*(have[j]-can_live);
can_live=0;
}
}
}
//printf("--%d %d\n",i,tmp);
output=min(output,tmp);
have[a[i].val]++;
}
printf("%d\n",output);
}
}