码迷,mamicode.com
首页 > 其他好文 > 详细

选数字 (select)

时间:2018-02-23 15:53:13      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:while   一点   inline   选择   git   space   sdi   0ms   二次   

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=1m,k<=1000
对于第 7,8 组数据 n=1m<=1000k<=1000000
对于所有数据 1<=n,m<=1000k<=10000001<=ai,j<=10000<=p<=100
样例解释
第一次选择第二列,第二次选择第二行,第三次选择第一行,第四次选择第二行,第五
次选择第一行,快乐值为 7+4+2+0+-2=11

暴力:80分

正解:预处理出选0-k个行的值(前缀和)以及0-k个列的值(前缀和)

         枚举选i个行以及k-i个列,但是要减去重复的部分,即行和列的交点处,共有i*(k-i)个焦点

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #define ll long long
 5 using namespace std;
 6 inline int read()
 7 {
 8     int x=0,w=1;char ch=getchar();
 9     while(!isdigit(ch)){if(ch==-) w=-1;ch=getchar();}
10     while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch-0),ch=getchar();
11     return x*w;    
12 }
13 const int N=1000100;
14 int n,m,k,p;
15 ll x[N],y[N];
16 priority_queue<ll>q1,q2;
17 int main()
18 {
19     freopen("select.in","r",stdin);
20     freopen("select.out","w",stdout);
21     n=read();m=read();k=read();p=read();
22     for(int i=1;i<=n;++i)
23      for(int j=1;j<=m;++j)
24      {
25          int o;o=read();
26          x[i]+=o;y[j]+=o;
27      }
28     for(int i=1;i<=n;++i) q1.push(x[i]),x[i]=0;
29     for(int j=1;j<=m;++j) q2.push(y[j]),y[j]=0;
30     for(int i=1;i<=k;++i)
31     {
32         ll tmp=q1.top();q1.pop();
33         x[i]=x[i-1]+tmp;
34         q1.push(tmp-p*m);
35     }
36     for(int i=1;i<=k;++i)
37     {
38         ll tmp=q2.top();q2.pop();
39         y[i]=y[i-1]+tmp;
40         q2.push(tmp-p*n);
41     }
42     ll ans=-1000000000000000ll;
43     for(int i=0;i<=k;++i)
44      ans=max(ans,x[i]+y[k-i]-p*(ll)i*(k-i));
45     printf("%lld",ans);
46     return 0;
47 }

最近目标:每一道题都要拿到预期分数。

保证这一点

选数字 (select)

标签:while   一点   inline   选择   git   space   sdi   0ms   二次   

原文地址:https://www.cnblogs.com/adelalove/p/8462073.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!