思路:
刚开始的时候和大多数萌新一样,先枚举每一行的和和每一列的和,依次选出个最小的行或列进行更新。
然后无尽的WA…
这种二维贪心的解法有后效性,参见网上一组数据:
3 3 30 2
10 10 10
1 1 99
20 20 99
一般解法:由于n很小,先对行所有的状态进行枚举,然后在对列进行贪心即可。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int n,m,k;
ll x,s[20][220];
bool v[20];
ll sum=0;
void dfs(int f,int q){
if(f==n||q==k){
ll w[220],ans=0;
memset(w,0,sizeof(w));
for(int i=0;i<m;i++){
for(int j=0;j<n;j++)
if(v[j])w[i]+=x;
else w[i]+=s[j][i];
}
sort(w,w+m);
int l=q;
for(int i=0;i<m;i++){
if(l<k&&w[i]<n*x){
ans+=n*x;
l++;
}
else ans+=w[i];
}
sum=max(sum,ans);
return;
}
dfs(f+1,q);
v[f]=1;
dfs(f+1,q+1);
v[f]=0;
}
int main()
{
cin>>n>>m>>x>>k;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>s[i][j];
memset(v,0,sizeof(v));
dfs(0,0);
cout<<sum<<endl;
return 0;
}