codeforce447 D - DZY Loves Modification 
题意:
有一个n*m的矩阵,每次可以选择一行或者一列,可以得到这行或这列的所有元素sum的积分,
然后使这一列/行的每一个元素都减少p,接着再选择一行或一列,共操作k次,n,m<=1000,k<=1000000
求最多能得到多少积分

思路:
每次选择sum最大的行或者列,但是时间复杂度太大,过不去~
若选择一行,则每个列的sum一定减少p,同理;
若选择的行数和列数确定下来了,选择i行,k-i列,那么行和列之间谁选选择就没有影响;
因为在选择行的时候,每一列都的sum都减少p,每一列的相对大小没有变化,前k-i大的列还是那几列,同列。
所以可以用优先队列O(n)预处理出row_sum[i]和col_sum[k-i]的值。选i行则消耗了每列的i*p的大小,共k-i列,故共消耗了i*(k-i)*p,答案为
max( row_sum[i], col_sum[k-i])- i*(k-i)*p

注意:!!!!!WA了很久T.T,因为i*(k-i)*p会超过int范围!!!

 1 /*===============================================================
 2 *   Copyright (C) 2014 All rights reserved.
 3 *   
 4 *   File Name: codeforces447_D_greedy.cpp
 5 *   Author:sunshine
 6 *   Created Time: 2014年07月23日
 7 *
 8 ================================================================*/
 9 #include <map>
10 #include <queue>
11 #include <stack>
12 #include <math.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <iostream>
16 #include <algorithm>
17 
18 using namespace std;
19 
20 int arr[1001][1001];
21 long long row_sum[1000001];
22 long long col_sum[1000001];
23 
24 int main(){
25     int n,m,k,p;
26     cin >> n >> m >> k >> p;
27         
28     priority_queue<int>row,col;
29         
30     for(int i = 0;i < n;i ++){
31         long long tmp =  0;
32         for(int j = 0;j < m;j ++){
33             cin >> arr[i][j];
34             tmp += arr[i][j];
35         }
36         row.push(tmp);
37     }
38 
39     for(int j = 0;j < m;j ++){
40         long long tmp = 0;
41         for(int i = 0;i < n;i ++){
42             tmp += arr[i][j];
43         }
44         col.push(tmp);
45     }
46         
47     row_sum[0] = 0;
48     for(int i = 1;i <= k;i ++){
49         row_sum[i] = row_sum[i - 1] + row.top();
50         row.push(row.top() - m * p);
51         row.pop();
52     }
53 
54     col_sum[0] = 0;
55     for(int i = 1;i <= k;i ++){
56         col_sum[i] = col_sum[i-1] + col.top();
57         col.push(col.top() - n * p);
58         col.pop();
59     }
60 
61     long long res = row_sum[0] + col_sum[k];
62     for(int i = 1;i <= k;i ++){
63         res = max(res, row_sum[i] + col_sum[k - i] - (long long)i * (k - i) * p);
64     }
65     cout << res << endl;
66     return 0;
67 }
View Code

相关文章: