链接: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;
}