给你一张桌子,有n条腿,告诉每条腿的长度(l)以及砍掉这条腿的花费(d),当最长腿的数量超过总数量的1/2,那么合法。问如何使得花费最小达到合法情况。
解法:
分别枚举以当前长度为最长的长度,砍去所有长度大于它的。删去长度小于它且花费最少的。
代码:
#include <stdio.h>
#include <ctime>
#include <math.h>
#include <limits.h>
#include <complex>
#include <string>
#include <functional>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <bitset>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
using namespace std;
const int MAXN = 100010;
int n;
int cnt[100010];
int val[100010];
int cost[210];
struct node
{
int L;
int D;
}a[MAXN], aa[MAXN];
bool cmp1(node a, node b)
{
if (a.L != b.L)
return a.L < b.L;
return a.D < b.D;
}
int main()
{
while (cin >> n)
{
memset(cnt, 0, sizeof(cnt));
memset(val, 0, sizeof(val));
memset(cost, 0, sizeof(cost));
for (int i = 1; i <= n; i++)
{
cin >> a[i].L;
cnt[a[i].L]++;
}
for (int i = 1; i <= n; i++)
cin >> a[i].D;
sort(a + 1, a + 1 + n, cmp1);
int sum = 0;
for (int i = n; i >= 1; i--)
{
sum += a[i].D;
if (a[i].L != a[i - 1].L)
{
val[a[i - 1].L] = sum;// 比a[i-1].l 长的桌腿的权值和是多少
}
}
int ans = val[a[1].L];
cost[a[1].D]++;
for (int i = 2; i <= n;i++)
{
if (a[i].L != a[i - 1].L)
{
int tmp = val[a[i].L];
int num_k = i - cnt[a[i].L];
if (num_k > 0)
{
for (int k = 1; k <= 200; k++)
{
if (cost[k])
{
if (cost[k] >= num_k)
{
tmp += k * num_k;
num_k = 0;
break;
}
else
{
tmp += k * cost[k];
num_k -= cost[k];
}
}
}
}
ans = min(ans, tmp);
}
cost[a[i].D]++;
}
cout << ans << endl;
}
return 0;
}