1. 程式人生 > >51Nod-1625-夾克爺發紅包(二進位制列舉+貪心)

51Nod-1625-夾克爺發紅包(二進位制列舉+貪心)

正解是列舉n行的全部情況,然後針對每種情況對m列進行貪心,求最大值,最後取最大值裡的最大值。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define fuck(x) cout<<#x<<" "<<x<<endl;
ll mp1[15][205],mp2[15][205];
ll colu[205];
vector<ll>v;
bool cmp(const ll&a,const ll&b)
{
    return a<b;
}
int main()
{
    ll n,m,x,cnm,t,cnt=0;
    ll ans=-1,tmp;
    scanf("%lld %lld %lld %lld",&n,&m,&x,&cnm);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%lld",&(mp1[i][j]));
    for(int k=0;k<(1<<n);k++)
    {
        cnt=tmp=0;
        for(int i=1;i<=n;i++)
        {
            if((k>>(i-1))&1)
            {
                cnt++;
                for(int j=1;j<=m;j++)
                    mp2[i][j]=x;
            }
            else
                for(int j=1;j<=m;j++)
                    mp2[i][j]=mp1[i][j];
        }
        if(cnt>cnm)
            continue;
        t=cnm-cnt;
        v.clear();
        for(int j=1;j<=m;j++)
        {
            for(int i=1;i<=n;i++)
            {
                if(i==1)
                    colu[j]=mp2[i][j];
                else
                    colu[j]+=mp2[i][j];
            }
            v.push_back(colu[j]);
        }
        sort(v.begin(),v.end(),cmp);
        for(int i=0;i<v.size();i++)
        {
            if(v[i]<n*x&&t>=1)
            {
                tmp+=n*x;
                t--;
            }
            else
                tmp+=v[i];
        }
        ans=max(ans,tmp);
    }
    printf("%lld\n",ans);
    return 0;
}