title: CodeForces 446B DZY Loves Modification 枚举 贪心
date: 2016-08-03 20:33:29
tags:
- 枚举
- 贪心
- CodeForces
题意:
给出一个n*m矩阵,对矩阵进行k次操作,每次操作使得矩阵中某一行或者某一列每一个数字都减p,同时得到的总价值加上该行/列减p之前所有数字之和
思路:
如果只对行/列操作是可以贪心的……但是可以同时存在行/列操作QAQ
然后操作的顺序对结果没有影响,所以可以枚举对行操作的次数i,然后再贪心算对行操作i次所得到的最大值和对列操作k-i次得到的最大值,相加之后减去pi(k-i),因为每对行操作一次,k-i次列操作就多加了p*(k-i)。
#include<bits/stdc++.h>
using namespace std;
long long INF =(1LL << 60);
const int MAXN = 1007;
long long num[MAXN][MAXN];
long long l[MAXN], h[MAXN];
long long hval[1000007], lval[1000007];
int main(int argc, char const *argv[])
{
long long n, m, k, p, x;
//freopen("in.txt", "r", stdin);
while(~scanf("%I64d%I64d%I64d%I64d", &n, &m, &k, &p))
{
memset(h, 0, sizeof(h));
memset(l, 0, sizeof(l));
memset(hval, 0, sizeof(hval));
memset(lval, 0, sizeof(lval));
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
scanf("%I64d", &num[i][j]);
}
}
priority_queue<long long> hh,ll;
for(long long i = 0; i < n; i++)
{
long long sum = 0;
for(long long j = 0; j < m; j++)
sum += num[i][j];
hh.push(sum);
}
for(long long j = 0; j < m; j++)
{
long long sum= 0;
for(long long i = 0; i < n; i++)
sum += num[i][j];
ll.push(sum);
}
for (int i = 1; i <= k; ++i)
{
long long x = hh.top();
hval[i] = hval[i-1]+x;
hh.pop();
hh.push(x-p*m);
long long y = ll.top();
lval[i] = lval[i-1]+y;
ll.pop();
ll.push(y-p*n);
}
long long ans = -INF;
for (int i = 0; i <= k; ++i)
{
ans = max(ans, lval[i]+hval[k-i]-i*(k-i)*p);
}
printf("%I64d
", ans);
}
return 0;
}