您的位置:首页 > 其它

cf557c

2016-03-04 18:53 281 查看
题目大意:

有一张桌子,有n个腿。第i根腿的长度是li。

现在要拿掉一些腿,使得桌子稳定,拿掉第i根腿需要di的能量。

稳定的条件是,假如拿掉若干条腿之后,桌子还有k个腿,那么长度最长的腿的数目要超过一半。比如桌子有5根腿,那么至少要有三根腿是最长的。另外,只有一根腿的桌子是稳定的,两个腿的桌子想要稳定,必需长度是一样的。

你的任务是拿掉若干腿,使得桌子稳定,并且所消耗的能量要最少。

思路:按长度排序,枚举每个长度,比枚举长度长的全拆掉,前面的拆掉 枚举长度数量-1

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <iomanip>

using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define maxn 100005
#define MOD 1000000007
#define mem(a , b) memset(a , b , sizeof(a))
#define LL long long
#define INF 100000000
int n;
int all = 0;
int cnt[205];
struct node
{
int l , val;
}a[maxn] , tmp[maxn];

bool cmp(node n1 , node n2)
{
if(n1.l == n2.l) return n1.val < n2.val;
return n1.l < n2.l;
}

bool cmp2(node n1 , node n2)
{
return n1.val < n2.val;
}

void solve()
{
int ans = INF;
int i = 0 , cost = 0 , num = 0 , j;
while(i < n)
{
cost = a[i].val;
// cnt[a[i].val]++;
num = 1;
for(j = i + 1; j < n ; j ++)
{
if(a[j].l == a[j-1].l) num++,cost+= a[j].val  ;
else break;
}
all-=cost;
cost = all;
/*  memcpy(tmp , a , (j-num)*8);
sort(tmp , tmp+j-num , cmp2);
int up = j + 1 - num - num;
for(int k = 0 ; k < up;k ++) cost += tmp[k].val;*/
int tmp = num;
num =  j + 1 - num - num;
//num++;
for(int k = 1 ; k <= 200 ; k ++)
{
if(cnt[k])
{
//  cout << k << endl;
if(cnt[k] < num) cost += k * cnt[k] , num -= cnt[k];
else {cost += k * num;break;}
}
}
ans = min(ans , cost);
//  cout << ans <<  " test" << endl;
for(int k = i ; k < j ; k++)
{
cnt[a[k].val]++;
}
i = j;
}
printf("%d\n" , ans);
}

int main()
{
while(scanf("%d" , &n) != EOF )
{
all = 0;
mem(cnt , 0);
for(int i = 0 ; i < n ;i ++)
scanf("%d" , &a[i].l);
for(int i = 0 ; i < n ; i ++)
scanf("%d" , &a[i].val) ,all += a[i].val;

sort(a , a + n , cmp);
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: