链接:https://ac.nowcoder.com/acm/problem/200190
来源:牛客网
题目描述
牛妹在玩一个名为矩阵消除的游戏,矩阵的大小是{n}n行{m}m列,第{i}i行第{j}j列的单元格的权值为a_{i,j}a
i,j
,牛妹可以进行{k}k个回合的游戏,在每个回合,牛妹可以选择一行或者选择一列,然后将这一行或者这一列的所有单元格中的权值变为{0}0,同时牛妹的分数会加上这一行或者这一列中的所有单元格的权值的和。
牛妹想最大化她的得分,球球你帮帮她吧!
输入描述:
第一行三个整数{n,m,k}n,m,k
接下来{n}n行每行{m}m个整数表示矩阵中各个单元格的权值。
输出描述:
输出一个整数表示牛妹能获得的最大分数。
示例1
输入
复制
3 3 2
101 1 102
1 202 1
100 8 100
输出
复制
414
备注:
数据范围n,m 1到15
a 1到1e6
0=<k<=n*m
因为n,m的范围比较小
可以使用01数组进行求解。
代码如下
下面展示一些 内联代码片
。
// A code block
var foo = 'bar';
// An highlighted block
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int maze[20][20];
int a[20],b[20];
bool flag[20];
int deal(int x)
{
int cnt=0;
int ans=1;
memset(flag,false,sizeof(flag));
while(x)
{
if(x&1)
{
cnt++;
flag[ans]=true;
}
ans++;
x>>=1;
}
return cnt;
}
int main()
{
int n,m,k;
cin>>n>>m>>k;
if(k>=m)k=m;
if(k>=n)
{
if(m>n)
k=m;
else
k=n;
}
for(int i=1;i<=n;i++)//输入
{
for(int j=1;j<=m;j++)
{
cin>>maze[i][j];
b[i]+=maze[i][j];//求每行总和
}
}
int sum=0;
int tmp=(1<<n)-1;//转化为01数组判断是否选择该行
long long maxn=0;
for(int f=0;f<=tmp;f++)
{
long long sum=0;
int ans=deal(f);//将数字转化为flag数组
ans=k-ans;
if(ans>m||ans<0)continue;
for(int i=1;i<=n;i++)
{
if(flag[i])
sum+=b[i];//将所选行加起来
}
memset(a,0,sizeof(a));//清除数组a
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(!flag[i]) a[j]+=maze[i][j];
}
}
sort(a+1,a+m+1);
for(int i=1,j=m;i<=ans;i++,j--)sum+=a[j];
maxn=max(maxn,sum);//维护最大值
}
cout<<maxn<<endl;
}