题目链接:https://ac.nowcoder.com/acm/contest/4090/C


#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,k;
int a[20][20];
long long h[20],r[20]; //记录每一行的和与每一列的和
int vis[20];
long long ans;
long long maxans;
int deal(int i) //对01枚举进行处理
{
memset(vis,0,sizeof(vis));
ans=0;
int t=1;
int res=0;
while(i)
{
if(i&1)
{
vis[t]=1;
ans+=r[t];
res++;
}
i>>=1;
t++;
}
return res;
}
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
r[j]+=a[i][j];
}
}
k=min(k,min(m,n));
int nh=1,nr=1;
int size=(1<<m)-1;
// int size=1<<m-1; 没加括号,wa了好几遍
//思路就是先枚举选了多少列,再进行的处理(选好列后要进行去重)
//利用01二进制枚举
for(int i=0;i<=size;i++)
{
nr=deal(i);
nh=k-nr;
if(nr>k||nh>k) //防止01枚举超过k
continue;
memset(h,0,sizeof(h));
for(int j=1;j<=n;j++)
{
for(int k=1;k<=m;k++)
{
if(!vis[k])
h[j]+=a[j][k];
}
}
sort(h+1,h+1+n,cmp);
for(int j=1;j<=nh;j++)
{
ans+=h[j];
}
maxans=max(maxans,ans);
}
cout<<maxans<<endl;
return 0;
}
本文介绍了一种解决二维矩阵中寻找特定行数和列数的最大子集和的算法。通过01枚举和排序策略,实现了在给定行数、列数和子集大小的情况下,找到矩阵中满足条件的最大子集和。该算法首先计算每一行和每一列的总和,然后通过枚举选择特定数量的列,并计算剩余未选列的行和,最后排序并选取前k个最大行和,从而得到最终的最大子集和。

被折叠的 条评论
为什么被折叠?



