1. 程式人生 > 實用技巧 >CodeForces 446B DZY Loves Modification 列舉 貪心

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\n", ans);
	}
	return 0;
}