zoukankan      html  css  js  c++  java
  • 二维背包 hdu2159

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159

    题目里面有两个限制条件,忍耐度和杀怪数量,所以可以用一个二维数组dp[i][j]来表示在消耗忍耐度i,并且杀怪数量为j时可以得到的最大经验,也可以用三维数组,但是因为每次的答案值依赖前一次的值,所以可以省略一维直接用二维数组。

    第一次做这种类型没想到用二维数组,开了两个一维数组做,现在有点觉得这个维数是不是就是限制条件的数量,我们用每一维的数组下标来表示每一种限制条件,那以后如果遇到三个限制条件,多个限制条件,那么是不是应该就是开多维数组来进行计算,感觉又更懂了那么一点点。

    我看博客之后的代码和第一次写的代码:

    看了博客之后:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<cstdio>
    #include<string>
    #include<deque> 
    using namespace std;
    typedef long long LL;
    #define eps 1e-8
    #define INF 0x3f3f3f3f
    #define maxn 105
    /*struct point{
        int u,w;
    };
    bool operator <(const point &s1,const point &s2)
    {
        if(s1.w!=s2.w)
        return s1.w>s2.w;
        else
        return s1.u>s2.u;
    }*/
    int dp[maxn][maxn];//dp[i][j]表示忍耐度消耗i,杀死怪物数量为j时可以获得的最大经验 
    int v[maxn],w[maxn];
    int n,m,k,t,s; 
    int main()
    {
        while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
        {
            for(int i=1;i<=k;i++)
            scanf("%d%d",&v[i],&w[i]);
            memset(dp,0,sizeof(dp));
            int ans=-1;
            for(int i=1;i<=m;i++)//忍耐度,第一个限制条件,这三个循环可以互换位置,但是因为题目要我们求 
            {                    //最后剩余的最大忍耐值,所以忍耐度放在第一层循环应该更快一点,可以跳出 
                for(int j=1;j<=s;j++)//杀怪数量,第二个限制条件 
                {
                    for(int e=1;e<=k;e++)//怪物种类 
                    {
                        if(i>=w[e])
                        dp[i][j]=max(dp[i][j],dp[i-w[e]][j-1]+v[e]);
                    }
                    if(dp[i][j]>=n)
                    {
                        ans=i;
                        break;
                     } 
                }
                if(ans!=-1)
                break;
             } 
             if(ans!=-1) 
             printf("%d
    ",m-ans);
             else
             printf("%d
    ",ans);
        }
        return 0;
    }

    开了两个一维数组的代码(经过讨论,下面代码是错的,但是偏偏过了,所以应该是后台数据有问题):

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<cstdio>
    #include<string>
    #include<deque> 
    using namespace std;
    typedef long long LL;
    #define eps 1e-8
    #define INF 0x3f3f3f3f
    #define maxn 105
    /*struct point{
        int u,w;
    };
    bool operator <(const point &s1,const point &s2)
    {
        if(s1.w!=s2.w)
        return s1.w>s2.w;
        else
        return s1.u>s2.u;
    }*/
    int n,m,k,s,t;
    int v[maxn],w[maxn],dp[maxn],num[maxn]; 
    int main()
    {
        while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
        {
            for(int i=1;i<=k;i++)
            scanf("%d%d",&v[i],&w[i]);
            memset(dp,0,sizeof(dp));//dp[i]表示消耗忍耐度i时可以得到的最大经验值 
            memset(num,0,sizeof(num));//记录杀怪数量,两个数组同步 
            for(int i=1;i<=k;i++)
            {
                for(int j=w[i];j<=m;j++)
                {
                    if(num[j-w[i]]+1<=s&&(dp[j]<dp[j-w[i]]+v[i]||dp[j]==dp[j-w[i]]+v[i]&&num[j]>num[j-w[i]]+1))
                    {//经验值放在第一位,然后杀怪数量第二位,但是前提是不能超出s 
                        dp[j]=dp[j-w[i]]+v[i];
                        num[j]=num[j-w[i]]+1;
                    }
                }
            }
            int ans=-1;
            for(int i=1;i<=m;i++)//找满足条件并且消耗最小忍耐度的结果 
            {
                if(dp[i]>=n)
                {
                    ans=m-i;
                    break;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    } 
  • 相关阅读:
    分治法的经典问题——大整数相乘
    分治法的经典问题——大整数相乘
    L2-013. 红色警报(dfs)
    L2-013. 红色警报(dfs)
    L2-012. 关于堆的判断
    L2-012. 关于堆的判断
    二进制和位运算中的异或
    2015年天勤考研机试模拟赛 A 推断三角形
    怎样利用kettle官方社区查找关于carte服务的设置
    openCV中 libopencv-nonfree-dev的安装: undefined reference to `cv::initModule_nonfree()&#39;
  • 原文地址:https://www.cnblogs.com/6262369sss/p/9846488.html
Copyright © 2011-2022 走看看