ZOJ 3715 Kindergarten Election
题目大意
意思就是这里有n个小朋友要选一个班长。
每一个小朋友都有一票,小朋友因为害羞不会投自己,只会投给他们最好的同学。现在1号小朋友想要当班长,而且是当唯一的班长,这就意味着他的票数必须要大于其他人的所有票。他可以通过买糖果给其他小朋友让他们把票投给他自己。
现在求1号当上班长需要花费的最小糖果数。
这道题目的思路就是枚举他最小的票数s,然后每次贪心找到每种情况的最小花费。
对于每种情况,都有:
- 先枚举2-n同学中票数大于等于s的。假设对于同学i有s+6票,那么在这s+6票中,找出花费糖果最小的7票。然后花费这么多糖果来争取他们的票数。
- 对于1号同学如果经历完第一步票数还不够s票。从剩下的票数中,每次找的最小花费的同学,依次花费糖果。 直到大于等于s票
#include<bits/stdc++.h>
using namespace std;
const int N = 107;
bool visited[N];
pair<int, int>par[N];
vector<int> vec[N];
int n;
int cal(int k)
{
memset(visited, false, sizeof(visited));
int ans = 0;
int s = vec[1].size();
for(int i=2; i<=n; ++ i)
{
if(vec[i].size() >= k)
{
for(int j=0; vec[i].size() - j >= k; ++ j)
{
int t = vec[i][j];
ans += par[t].first, visited[t] = true, ++ s;
}
}
}
if(s < k)
{
for(int i=0; i<n-1; ++ i)
{
if(visited[i] == false && par[i].second != 1)
ans += par[i].first, ++ s;
if(s >= k)
break;
}
}
return ans;
}
int solve()
{
cin >> n;
for(int i=0; i<n-1; ++ i)
cin >> par[i].second;
for(int i=0; i<n-1; ++ i)
cin >> par[i].first;
sort(par, par+n-1);
for(int i=1; i<=n; ++ i)
vec[i].clear();
for(int i=0; i<n-1; ++ i)
vec[par[i].second].push_back(i);
int ans = INT_MAX;
for(int i = max((int)vec[1].size(), 1); i<=n-1; ++ i)
{
ans = min(ans, cal(i));
//cout << i << ":" << ans << endl;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int t;
cin >> t;
for(int i=1; i<=t; ++ i)
cout << solve() << endl;
return 0;
}
标签:
贪心
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· 编程神器Trae:当我用上后,才知道自己的创造力被低估了多少
· C# 从零开始使用Layui.Wpf库开发WPF客户端
· C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)
· 上周热点回顾(3.17-3.23)