CodeForces 446B DZY Loves Modification 枚举 贪心


title: CodeForces 446B DZY Loves Modification 枚举 贪心
date: 2016-08-03 20:33:29
tags:
- 枚举
- 贪心
- CodeForces

链接:
DZY Loves Modification

题意:
给出一个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;
}
原文地址:https://www.cnblogs.com/nanf/p/CodeForces446B.html