因为n很小 直接2^n找出每行分配高级红包的情况 在行确定的情况下 就可以对列进行贪心了
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll mat[50][200];
ll x,ans;
int pre[50];
int n,m,k,cnt;
void solveI()
{
ll tem[50][200];
ll sum;
int i,j;
memcpy(tem,mat,sizeof(mat));
for(i=1;i<=cnt;i++)
{
for(j=1;j<=m;j++)
{
tem[pre[i]][j]=x;
}
}
sum=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
sum+=tem[i][j];
}
}
ans=max(ans,sum);
return;
}
void dfsI(int cur)
{
if(cnt==k||cur==n+1)
{
solveI();
return;
}
dfsI(cur+1);
pre[++cnt]=cur;
dfsI(cur+1);
cnt--;
return;
}
void solveII()
{
ll tem[50][200];
ll col[200];
ll sum,t;
int i,j;
memcpy(tem,mat,sizeof(mat));
for(i=1;i<=cnt;i++)
{
for(j=1;j<=m;j++)
{
tem[pre[i]][j]=x;
}
}
memset(col,0,sizeof(col));
sum=0;
for(j=1;j<=m;j++)
{
for(i=1;i<=n;i++)
{
col[j]+=tem[i][j];
}
sum+=col[j];
}
sort(col+1,col+m+1);
for(i=1;i<=m;i++)
{
t=n;
if(col[i]<t*x&&i<=k-cnt) sum+=(t*x-col[i]);
else break;
}
ans=max(ans,sum);
return;
}
void dfsII(int cur)
{
if(cur==n+1)
{
solveII();
return;
}
dfsII(cur+1);
pre[++cnt]=cur;
dfsII(cur+1);
cnt--;
return;
}
int main()
{
int i,j;
scanf("%d%d%lld%d",&n,&m,&x,&k);
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%lld",&mat[i][j]);
}
}
if(k<=n)
{
ans=0,cnt=0;
dfsI(1);
printf("%lld\n",ans);
}
else
{
ans=0,cnt=0;
dfsII(1);
printf("%lld\n",ans);
}
return 0;
}