I、How to sort

https://ac.nowcoder.com/acm/contest/554/I

1、考虑数字成环来移动肯定是最优的。

2、如果发现了一个环,假设环上有k个数字,那么使用k个数字中最小的数字来移动其他数字应该是较优的。

此时这个环的贡献为 环上最小值*(k-1)+环上除最小值之外的其他值。

3、但是,在第二点的基础上,一直83.3%,然后发现了,第二点并不一定是最优,你可以考虑使用环外的最小数来移动这个环上的数字,虽然多移动了一次,但是贡献有可能会更小。

此时贡献为 环上的所有值+环上的最小值+整个序列的最小值*(n+1)

4、第二点和第三点取一下min,就可以了,记得要先hash一下。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[10005], t[10005], cnt;
bool book[10005];
int has(int k)
{
	return lower_bound(t, t + cnt, k) - t;
}
int main()
{
	int n, MIN = 1e9;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &a[i]);
		t[i] = a[i];
		MIN = min(MIN, a[i]);
	}
	sort(t + 1, t + 1 + n);
	cnt = unique(t + 1, t + n + 1) - t - 1;
	for (int i = 1; i <= n; i++)
		a[i] = lower_bound(t + 1, t + 1 + cnt, a[i]) - t;
	ll ans = 0;
	for (int i = 1; i <= n; i++)
	{
		if (book[i] == false)
		{
			book[i] = true;
			ll sum = 0, minn = t[a[i]];
			int cnt = 1;
			sum += t[a[i]];
			for (int j = a[i]; j != i; j = a[j])
			{
				book[j] = true;
				sum += t[a[j]];
				minn = min(minn, 1LL * t[a[j]]);
				cnt++;
			}
			if (cnt != 1)
				ans += min(sum + minn * (cnt - 2), minn + sum + (cnt + 1) * MIN);
		}
	}
	printf("%lld", ans);
}
全部评论

相关推荐

沉淀一会:**圣经 1.同学你面试评价不错,概率很大,请耐心等待;2.你的排名比较靠前,不要担心,耐心等待;3.问题不大,正在审批,不要着急签其他公司,等等我们!4.预计9月中下旬,安心过节;5.下周会有结果,请耐心等待下;6.可能国庆节前后,一有结果我马上通知你;7.预计10月中旬,再坚持一下;8.正在走流程,就这两天了;9.同学,结果我也不知道,你如果查到了也告诉我一声;10.同学你出线不明朗,建议签其他公司保底!11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
沉淀一会:1.同学你面试评价不错,概率很大,请耐心等待; 2.你的排名比较靠前,不要担心,耐心等待; 3.问题不大,正在审批,不要着急签其他公司,等等我们! 4.预计9月中下旬,安心过节; 5.下周会有结果,请耐心等待下; 6.可能国庆节前后,一有结果我马上通知你; 7.预计10月中旬,再坚持一下; 8.正在走流程,就这两天了; 9.同学,结果我也不知道,你如果查到了也告诉我一声; 10.同学你出线不明朗,建议签其他公司保底! 11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务