本题的思路是,通过位运算来枚举选行还是选列,然后用一个数组存下每个位运算,也能算出有多少个选列,先用一个数组存下每个行,然后再把选入的行相加,然后把没有选入行的列数相加入进去一个数组,然后再排序一下,把满足条件的列数加入进去,然后再维护最大值。。。
# include <iostream>
# include <algorithm>
# include <cstring>
# include <cstdio>
using namespace std;
const int N=20;
long long sh[N],sl[N];
int s[N][N];
int n,m,k;
long long ans=0;
int b[N];
int deal(int t){
memset(b,0,sizeof(b));
int cnt=0;
int i=1;
while(t){
if((t&1)) {
cnt++;
b[i]=1;
}
t>>=1;
i++;
}
return cnt;
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&s[i][j]);
sh[i]+=s[i][j];
}
}
if(k>n) k=n;
if(k>m) k=m;
int num=(1<<n)-1;
long long sum=0;
for(int i=0;i<=num;i++){
sum=0;
int temp=deal(i);
int temp2=k-temp;
if(temp2<0||temp2>m) continue;
for(int i=1;i<=n;i++){
if(b[i]) sum+=sh[i];
}
memset(sl,0,sizeof(sl));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!b[i]){
sl[j]+=s[i][j];
}
}
}
sort(sl,sl+m+1);
for(int i=m,j=1;j<=temp2;i--,j++){
sum+=sl[i];
}
ans=max(ans,sum);
}
printf("%d\n",ans);
return 0;
}总结: 听了思路之后,但还是不太会写,代码力太弱了,看来要多做这种有挑战性的题目。。其实选入行不用改变他的值,因为不需要去选他就行,,然后把列数加入进去就行。。

京公网安备 11010502036488号