本题的思路是,通过位运算来枚举选行还是选列,然后用一个数组存下每个位运算,也能算出有多少个选列,先用一个数组存下每个行,然后再把选入的行相加,然后把没有选入行的列数相加入进去一个数组,然后再排序一下,把满足条件的列数加入进去,然后再维护最大值。。。

# 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;
}

总结: 听了思路之后,但还是不太会写,代码力太弱了,看来要多做这种有挑战性的题目。。其实选入行不用改变他的值,因为不需要去选他就行,,然后把列数加入进去就行。。