选数字

选数字 (select)

Time Limit:3000ms   Memory Limit:64MB

【题目描述】

LYK找到了一个n*m的矩阵,这个矩阵上都填有一些数字,对于第i行第j列的位置上的数为ai,j。由于它AK了noip2016的初赛,最近显得非常无聊,便想到了一个方法自娱自乐一番。它想到的游戏是这样的:每次选择一行或者一列,它得到的快乐值将会是这一行或者一列的数字之和。之后它将该行或者该列上的数字都减去p(之后可能变成负数)。如此,重复k次,它得到的快乐值之和将会是它NOIP2016复赛比赛时的RP值。LYK当然想让它的RP值尽可能高,于是它来求助于你。

 【输入格式】(select.in)

  第一行4个数n,m,k,p。

  接下来n行m列,表示ai,j。

【输出格式】(select.out)

  输出一行表示最大RP值。

【输入样例】

  2 2 5 2

  1 3

  2 4

【输出样例】

  11

【数据范围】 

  总共10组数据。

  对于第1,2组数据n,m,k<=5。

  对于第3组数据k=1。

  对于第4组数据p=0。

  对于第5,6组数据n=1,m,k<=1000。

  对于第7,8组数据n=1,m<=1000,k<=1000000。

  对于所有数据1<=n,m<=1000,k<=1000000,1<=ai,j<=1000,0<=p<=100。

 

【样例解释】

  第一次选择第二列,第二次选择第二行,第三次选择第一行,第四次选择第二行,第五次选择第一行,快乐值为7+4+2+0+-2=11。

【题目分析】

  没什么。你枚举选择i行,k-i列,...然后处理出这种选择的答案,最后取大,注意答案初值要赋成一个较大的负数

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <queue>
 5 using namespace  std;
 6 #define R register
 7 #define INF 100000000000000LL
 8 #define ll long long
 9 inline ll read()
10 {
11     R char ch; ll t = 0; R bool flag = 0;
12     while (!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));
13     ch == '-' ? flag = 1 : t = ch - '0';
14     while (((ch = getchar()) >= '0') && (ch <= '9')) t = t * 10 + ch - '0';
15     if (flag) t = -t; return t;
16 }
17 priority_queue<ll> q1, q2;
18 ll xx[1000100], yy[1000100],x[1100], y[1100];
19 ll n, m, k, p;
20 ll ans;
21 void work()
22 {
23     xx[0] = 0;
24     yy[0] = 0;
25     for (ll i = 1; i <= n; i ++) q1.push(x[i]);
26     for (ll i = 1; i <= k; i ++)
27     {
28         R ll t = q1.top();
29         xx[i] = xx[i - 1] + t;
30         q1.pop();
31         q1.push(t - p * m);
32     }
33     for (ll i = 1; i <= m; i ++) q2.push(y[i]);
34     for (ll i = 1; i <= k; i ++)
35     {
36         R ll t = q2.top();
37         yy[i] = yy[i - 1] + t;
38         q2.pop();
39         q2.push(t - p * n);
40     }
41     ans = -INF;
42     for (int i = 0; i <= k; i ++)
43         ans = max(ans, xx[i] + yy[k - i] - p * (k - i) * i);
44 }
45 int main()
46 {
47     freopen("select.in", "r", stdin);
48     freopen("select.out", "w", stdout);
49     n = read(); m = read(); k = read(); p = read();
50     for (ll i = 1; i <= n; i ++)
51         for (ll j = 1; j <= m; j ++)
52         {
53             ll xxx = read();
54             x[i] += xxx;
55             y[j] += xxx;
56         }
57     work();
58     cout << ans;
59 }

 

posted @ 2016-11-06 15:17  [lemon]  阅读(380)  评论(0编辑  收藏  举报
……