Educational Codeforces Round 21-E-贪心背包or

来源:互联网 发布:生物 知乎 编辑:程序博客网 时间:2024/06/08 00:27

链接:点击打开链接


题解:一.可以按单位价值排序,然后一直取到超过m为止,这里可以知道要是正好取到m那么这个配置肯定是最优的,剩下的两种情况就是m-1,和m-2那么就要dp四种情况,1.从剩下的拿出填满它.2.从已取当中拿去一出来从剩下的拿2进去.3...4...以此类推,可以发现我们最后只需要dp剩下1-5的质量就可以了

二.考虑质量1和质量2的情况的最优,最后再对质量3枚举就行了。


一:

#include <iostream>#include <cstdio>#include <algorithm>#include <cstdlib>#include <cstring>#include <string>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>using namespace std;typedef long long LL;const LL INF=1e12L;const int inf=0x3f3f3f3f;const int maxn=1e5+5;const int Mod=1e9+7;struct Souvenirs{    int w,c;    bool friend operator<(Souvenirs x,Souvenirs y){        return ((double)x.c/x.w) > ((double)y.c/y.w);    }}a[maxn];int n,m;int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)  scanf("%d%d",&a[i].w,&a[i].c);    sort(a+1,a+n+1);    int up=0;    LL ans=0;    LL d[3][3]={INF,INF,INF,INF,INF},id=0;    int i=1;    for(i=1;i<=n;i++){        if(up+a[i].w>m)  break;        up+=a[i].w;        ans+=a[i].c;    }    for(int j=i-1;j>=1;j--){    if(a[j].w==1){    if(d[0][id]==INF)  d[0][id]=a[j].c, id= id==2? 0:id+1;}    else if(d[a[j].w-1][0]==INF)  d[a[j].w-1][0]=a[j].c;}LL sum=ans,num=min(d[2][0],min(d[1][0]+d[0][0] , d[0][0]+d[0][1]+d[0][2]));//num是取三个出来最小的值 LL dp[6]={0};    while(i<=n){    for(int j=5;j>=a[i].w;j--)    dp[j]=max(dp[j],dp[j-a[i].w]+a[i].c);    i++;}id=m-up; if(id<3){ans=max(ans,sum+dp[id++]);        ans=max(ans,sum-d[0][0]+dp[id++]);        ans=max(ans,sum-min(d[1][0],d[0][0]+d[0][1])+dp[id++]);        ans=max(ans,sum-num+dp[id++]);}printf("%I64d\n",ans);    return 0;}

二:

#include<cstdio>  #include<cstring>  #include<algorithm>#include<cmath>#include<set> #include<iostream>using namespace std;  #define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define inf 0x3f3f3f3fconst int mx=1e5+10;typedef long long ll;using namespace std;int n,m,k;struct node{ll v,x,y;}dp[3*mx];ll a[3][mx],size[3];bool cmp (ll a,ll b){  return a>b;  }int main(){while(~scanf("%d%d",&n,&m)){int x,y;size[0]=size[1]=size[2]=0;for(int i=1;i<=n;i++){scanf("%d%d",&x,&y);a[x-1][++size[x-1]]=y;}for(int i=0;i<=m;i++) dp[i].v=dp[i].x=dp[i].y=0;for(int i=0;i<=2;i++)  sort(a[i]+1,a[i]+1+size[i],cmp);for(int i=0;i<=m;i++){if(dp[i].x<size[0]&&dp[i+1].v<=dp[i].v+a[0][dp[i].x+1]){dp[i+1].v=dp[i].v+a[0][dp[i].x+1];dp[i+1].y=dp[i].y;dp[i+1].x=dp[i].x+1;}if(dp[i].y<size[1]&&dp[i+2].v<=dp[i].v+a[1][dp[i].y+1]){dp[i+2].v=dp[i].v+a[1][dp[i].y+1];dp[i+2].y=dp[i].y+1;dp[i+2].x=dp[i].x;}if(i&&dp[i].v<dp[i-1].v) dp[i]=dp[i-1];  }for(int i=1;i<=size[2];i++) a[2][i]+=a[2][i-1];ll ans=0;for(int i=0;i<=size[2];i++){int kep=m-3*i;if(kep>=0)  ans=max(ans,a[2][i]+dp[kep].v);}cout<<ans<<endl;}return 0;} 


阅读全文
0 0