选数字 (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 }