链接:https://ac.nowcoder.com/acm/contest/4090/C
牛妹在玩一个名为矩阵消除的游戏,矩阵的大小是{n}n行{m}m列,第{i}i行第{j}j列的单元格的权值为a_{i,j}ai,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
备注:
1\leq n,m\leq 151≤n,m≤15
1\leq a_{i,j}\leq 1e61≤ai,j≤1e6
1\leq k\leq n*m1≤k≤n∗m
代码:
#include <bits/stdc++.h>
using namespace std;
long long n,m,k,s=0;
long long a[20][20],b[20][20];
long long c[20],max1,p[20];
void dfs(int id,long long sum,int t,int tip)
{
if(tip==t)
{
for(int i=1;i<=m;i++)
{
p[i]=0;
for(int j=1;j<=n;j++)
{
if(c[j]==0)
p[i]+=a[j][i];
}
}
sort(p+1,p+1+m);
for(int i=m;i>=1;i--)
{
if(t==k)
break;
else
{
t++;
sum+=p[i];
}
}
max1=max(max1,sum);
return;
}
if(id>n)
return;
c[id]=1;
long long ss=0;
for(int i=1;i<=m;i++)
{
ss+=a[id][i];
}
dfs(id+1,sum+ss,t,tip+1);
c[id]=0;
dfs(id+1,sum,t,tip);
}
void bfs(int id,long long sum,int t,int tip)
{
if(tip==t)
{
for(int i=1;i<=n;i++)
{
p[i]=0;
for(int j=1;j<=m;j++)
{
if(c[j]==0)
p[i]+=a[i][j];
}
}
sort(p+1,p+1+n);
for(int i=n;i>=1;i--)
{
if(t==k)
break;
else
{
t++;
sum+=p[i];
}
}
max1=max(max1,sum);
return;
}
if(id>m)
return;
c[id]=1;
long long ss=0;
for(int i=1;i<=n;i++)
{
ss+=a[i][id];
}
bfs(id+1,sum+ss,t,tip+1);
c[id]=0;
bfs(id+1,sum,t,tip);
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
s+=a[i][j];
}
}
if(k>=min(n,m))
{
cout<<s<<endl;
}
else
{
s=0;
if(n<=m)
{
max1=0;
for(int i=0;i<=k;i++)
{
memset(c,0,sizeof(c));
dfs(1,0,i,0);
}
cout<<max1<<endl;
}
else
{
max1=0;
for(int i=0;i<=k;i++)
{
memset(c,0,sizeof(c));
bfs(1,0,i,0);
}
cout<<max1<<endl;
}
}
}