[贪心] 冥土追魂 Wannafly挑战赛26

链接:https://www.nowcoder.com/acm/contest/212/B
来源:牛客网
 

冥土追魂

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

有一天 Misaka 和 Kuroko 在玩一个关于冥土追魂的游戏....
Misaka和Kuroko在一个 n x m 的棋盘上玩游戏,每个格子上都放着一些呱太。游戏共进行 k 回合,每一回合 Kuroko会选**有呱太**的一行 i,在这之后Misaka会选择一列 j ,并拿走格子 (i, j) 上的所有呱太,Misaka希望自己拿走的呱太尽可能多,而Kuroko不想让Misaka拿走很多呱太,所以她希望拿走的呱太尽可能少。
在一旁围观的恒温死神希望预测结果,请你预测在双方都采取最优策略的情况下,Misaka最终能拿走呱太的数量。

输入描述:

第一行三个数 n, m, k。 
接下来 n 行,每行 m 个数,第 i 行第 j 个数表示棋盘第 i 行第 j 列上的呱太数量 ai,j。

输出描述:

输出共一个数,表示在你的预测下,Misaka最终能拿走呱太的数量。

示例1

输入

复制

3 2 4
5 7
3 2
8 5

输出

复制

17

备注:

1≤ n, m ≤ 1000, 1 ≤ k ≤ n x m, 1 ≤ ai,j ≤ 109
一行选完时最优
先选取 k / m 行, 再选取 k % m 个
如不能整除 枚举不取完的行, 在剩下的行中取和最小的 k / m 行

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int mn = 1010;

int a[mn][mn];
struct node
{
	int id;
	ll sum;
} s[mn];
bool cmp(const node& a, const node& b)
{
	return a.sum < b.sum;
}

int main()
{
	int n, m, k;
	scanf("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= n; i++)
	{
		s[i].id = i;
		for (int j = 1; j <= m; j++)
		{
			scanf("%d", &a[i][j]);
			s[i].sum += a[i][j];
		}
		sort(a[i] + 1, a[i] + m + 1, greater<int>());
	}
	sort(s + 1, s + n + 1, cmp);

	ll ans = 1e18;
	int p = k / m, q = k % m;
	if (q == 0)
	{
		ans = 0;
		for (int i = 1; i <= p; i++)
			ans += s[i].sum;
	}
	else if (q != 0)
	{
		for (int i = 1; i <= n; i++)
		{
			ll res = 0;
			for (int j = 1; j <= q; j++)
				res += a[s[i].id][j];
				
			int t = p;
			for (int j = 1; j <= t; j++)
			{
				if (j == i)
				{
					t++;
					continue;
				}
				res += s[j].sum;
			}
			ans = min(ans, res);
		}
	}
	printf("%lld\n", ans);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ummmmm/article/details/83062976