题意:如果最长长度的凳脚数量超过总凳脚数的一半,则认为这个凳子是稳定的。现在有张凳子,有n个凳脚,分别分出长度和砍掉该凳脚的费用。问你要使得凳子稳定的最小费用。
之前用了一次暴力做法超时了,即对每个可能的ai,就把所有长度比ai小的腿 尽量选短的 选到符合条件为止
然而试一下从大的开始选,,居然就ac了。。。还62ms。。看来是数据太弱,,,目前还没想到比较好的解法
------------------------------------
预处理好每个长度有多少根
枚举每个ai为 maxlength
然后对n~1 (以拆除力气值排序) 暴力选择前x个力气值最大的腿
那么用所有拆除力气和tol减去 choose到的腿,得到的一定是以ai为maxlength下的最小拆除力气和
遍历ai 每次取最小的 答案
最后输出
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define inf 0x7f7f7f7f
using namespace std;
const int maxn = 100005;
int min(int a,int b)
{return a<b?a:b;}
struct node
{
int l;
int e;
} tm[maxn];
struct pack
{
int l;
int sum;
int size;
} nm[maxn];
int cmp(node a,node b)
{
return a.l<b.l;
}
int cmp2(node a,node b)
{
return a.e<b.e;
}
int main()
{
int tol=0;;
int n,j,k,i,m,tmp;
cin>>n;
int maxx=0;
for (i=1;i<=n;i++)
{
scanf("%d",&tm[i].l);
}
for (i=1;i<=n;i++)
{
scanf("%d",&tm[i].e);
tol+=tm[i].e;
}
sort(tm+1,tm+1+n,cmp); //以长度排序,方便统计
nm[1].l=tm[1].l;
nm[1].sum=tm[1].e;
nm[1].size++;
int ok=1; //ok为不同长度的种类数
for (i=2;i<=n;i++)
{
if (tm[i].l==tm[i-1].l)
{
nm[ok].sum+=tm[i].e; //累计拆掉该长度所有腿的力气之和
nm[ok].size++; //长度为nm[i].l的腿有多少根
}
else
{
++ok;
nm[ok].l=tm[i].l;
nm[ok].sum+=tm[i].e;
nm[ok].size++;
}
}
sort(tm+1,tm+1+n,cmp2); //以力气排序,方便枚举
if (n==1)
{
printf("0\n");
return 0;
}
if (n==2)
{
if (tm[1].l==tm[2].l)
printf("0\n");
else
{
printf("%d\n",min(tm[1].e,tm[2].e));
}
return 0;
}
int minn=inf;
for (i=ok;i>=1;i--)
{
int has=nm[i].size; //该maxlength腿有多少跟
int x=nm[i].l; //长度
int need=has*2-1-has; //如果该腿为maxlength,需要再拿多少跟比它短的腿才平衡
int choose=nm[i].sum; //已经选了的腿(maxlenght的数量)
for(j=n;j>=1&&need;j--)
{
if (tm[j].l>=x) continue; //长度大于x则丢弃
need--;
choose+=tm[j].e; //选上该腿
}
minn=min(minn,tol-choose); //取最小的答案
}
printf("%d\n",minn);
return 0;
}