hdu2602+2191+1864

本文介绍了HDU三道动态规划题目2602、2191和1864的解法,强调了在开dp数组大小时避免造成运行错误的重要性。2602是01背包模板题,2191中需根据自身金钱最大化大米袋数,1864则需处理浮点数输入并正确设定数组大小。
摘要由CSDN通过智能技术生成

hdu2602+2191+1864

这三道题依然是dp,需要注意的是开dp数组的大小,因为这个RE过;

2602

这是一道01背包模板题

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<mem.h>
#include<math.h>
using namespace std;
int i,j,T,N,V,v[1005],w[1005],dp[1005];
int main()
{
    while(~scanf("%d",&T))
    {
        while(T--)
        {
            memset(dp,0,sizeof(dp));
            memset(v,0,sizeof(v));
            memset(w,0,sizeof(w));
            scanf("%d%d",&N,&V);
            for(i=1;i<=N;i++) scanf("%d",&w[i]);
            for(i=1;i<=N;i++) scanf("%d",&v[i]);
            for(i=1;i<=N;i++)
            {
                for(j=V;j>=v[i];j--)
                {
                    dp[j] = max(dp[j],dp[j-v[i]]+w[i]);
                }
            }
            printf("%d\n",dp[V]);
        }
    }
    return 0;
}

2191

这道题中“背包”的容量是自己有的钱,最大化的“价值”是大米的袋数,需要按袋数来往w和v数组中填数

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<mem.h>
#include<math.h>
using namespace std;
int i,j,dp[2005],n,m,p,h,c,C,w[2005],v[2005],cnt;
int main()
{
    while(~scanf("%d",&C))
    {
        while(C--)
        {
            cnt=1;
            memset(dp,0,sizeof(dp));
            memset(w,0,sizeof(w));
            scanf("%d%d",&n,&m);
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&p,&h,&c);
                for(j=1;j<=c;j++)
                {
                    w[cnt] = p;
                    v[cnt] = h;
                    cnt++;
                }
            }
            for(i=1;i<cnt;i++)
            {
                for(j=n;j>=w[i];j--)
                {
                    dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
                }
            }
            printf("%d\n",dp[n]);
        }
    }
    return 0;
}

1864

这道题首先要处理输入格式,由于价值是小数点后两位,将所有的浮点数乘以100来处理。注意百度上的第一个博客代码是错误的,还是要按照将拥有的报销额度作为“背包”的容量来写。要注意开数组的大小,如果太小会RE,这里开了301000100+50维

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<mem.h>
#include<math.h>
using namespace std;
int i,j,n,m,cnt,dp[3000050],a[35],sA,sB,sC,Q;
char ch;
double q,sumA,sumB,sumC,pr;
int main()
{
    while(~scanf("%lf%d",&q,&n))
    {
        if(n==0) break;
        cnt=1;
        memset(a,0,sizeof(a));
        Q = int(q*100);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&m);
            getchar();
            sumA=0;sumB=0;sumC=0;
            int flag=0;
            for(j=1;j<=m;j++)
            {    
                scanf("%c",&ch);
                getchar();
                scanf("%lf",&pr);
                if(ch == 'A') sumA+=pr;
                else if(ch == 'B') sumB+=pr;
                else if(ch == 'C') sumC+=pr;
                else flag=1;
                getchar();
            }
            if(flag==1) continue;
            sA = (int)(sumA * 100);
            sB = (int)(sumB * 100);
            sC = (int)(sumC * 100);
            if(sA<=60000 && sB<=60000 && sC<=60000 && (sA+sB+sC)<=100000)
            {
                a[cnt++] = (sA+sB+sC);
            }
        }
        memset(dp,0,sizeof(dp));
        for(i=1;i<cnt;i++)
        {
            for(j=Q;j>=a[i];j--)
            {
                dp[j] = max(dp[j],dp[j-a[i]] + a[i]);
            }
        }
        printf("%.2lf\n",dp[Q]/100.0);
    }
    return 0;
}

2020/11/17

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值