codeforces 417D Cunning Gena

来源:互联网 发布:智百威软件免费下载 编辑:程序博客网 时间:2024/05/17 22:30

题意:有m道题,要分给n个朋友解决,每个朋友有不同的条件,酬劳,且每个朋友要至少k个显示器连接作者电脑才肯帮忙,所以作者需要买至少k个显示器。求解决所有问题所需最少的钱。

分析:可以状压20个问题,实际是二维,dp[i][s]表示用前i个人解决s(二进制,解决问题的集合)所需最少钱,由于爆内存可省略第一维。正确的做法是先根据显示器数目将朋友排序,我纠结的是不排序维护一个mx数组表示s状态显示器的最大值会wa在第24发。

正确代码:

#include<iostream>#include<string>#include<cstring>#include<cstdio>#include<cmath>#include<iomanip>#include<map>#include<algorithm>#include<queue>#include<set>#define inf 2e18#define pi acos(-1.0)#define eps 1e-8#define seed 131using namespace std;typedef pair<int,int> pii;typedef unsigned long long ULL;typedef long long LL;const int maxn=100005;int n,m,b;LL dp[1<<20];struct Node{    int x;    int k;    int s;    bool operator<(const Node& a)const    {        return k<a.k;    }}fr[105];int main(){    scanf("%d%d%d",&n,&m,&b);    int u;    for(int i=1;i<=n;i++){        scanf("%d%d%d",&fr[i].x,&fr[i].k,&u);        int ans=0;        int d;        for(int j=0;j<u;j++)        {            scanf("%d",&d);            ans^=(1<<(d-1));        }        fr[i].s=ans;    }    sort(fr+1,fr+n+1);    dp[0]=0;    for(int i=1;i<(1<<m);i++)        dp[i]=inf;    LL res=inf;    for(int i=1;i<=n;i++){        for(int j=0;j<(1<<m);j++){            dp[j|fr[i].s]=min(dp[j|fr[i].s],dp[j]+fr[i].x);//正推        }        res=min(res,dp[(1<<m)-1]+fr[i].k*(LL)b);    }    if(res==inf)        res=-1;    cout<<res;    return 0;}
错误代码:

#include<iostream>#include<string>#include<cstring>#include<cstdio>#include<cmath>#include<iomanip>#include<map>#include<algorithm>#include<queue>#include<set>#define inf 2e18#define pi acos(-1.0)#define eps 1e-8#define seed 131using namespace std;typedef pair<int,int> pii;typedef unsigned long long ULL;typedef long long LL;const int maxn=100005;int n,m,b;LL dp[1<<20];int mx[1<<20];struct Node{    int x;    int k;    int s;    bool operator<(const Node& a)const    {        return k<a.k;    }}fr[105];int main(){    scanf("%d%d%d",&n,&m,&b);    int u;    for(int i=1;i<=n;i++){        scanf("%d%d%d",&fr[i].x,&fr[i].k,&u);        int ans=0;        int d;        for(int j=0;j<u;j++)        {            scanf("%d",&d);            ans^=(1<<(d-1));        }        fr[i].s=ans;    }    //sort(fr+1,fr+n+1);    dp[0]=0;    mx[0]=0;    for(int i=1;i<(1<<m);i++){        dp[i]=inf;        mx[i]=-1e9;    }    LL res=inf;    for(int i=1;i<=n;i++){        for(int j=0;j<(1<<m);j++){            if(dp[j]<inf){                LL sum=dp[j]+fr[i].x;                if(fr[i].k>mx[j])                    sum+=(fr[i].k-mx[j])*(LL)b;                if(sum<dp[j|fr[i].s]){                    dp[j|fr[i].s]=sum;                    mx[j|fr[i].s]=max(fr[i].k,mx[j]);                }            }        }        res=min(res,dp[(1<<m)-1]);    }    if(res==inf)        res=-1;    cout<<res;    return 0;}



0 0
原创粉丝点击