51nod-1625 夹克爷发红包

[题目链接]

思路: 刚开始的时候和大多数萌新一样,先枚举每一行的和和每一列的和,依次选出个最小的行或列进行更新。
然后无尽的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;
}

猜你喜欢

转载自blog.csdn.net/zzti_xiaowei/article/details/80781620
今日推荐