您的位置:首页 > 其它

Codeforces 557C Arthur and Table 暴力水过得题。。。

2015-08-23 16:07 253 查看
题意:如果最长长度的凳脚数量超过总凳脚数的一半,则认为这个凳子是稳定的。现在有张凳子,有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: