zoukankan      html  css  js  c++  java
  • 01背包 hdu 2602

    这题就是一个最基本的0-1背包。刚学DP的人(比如说我)拿来上手应该是很不错的。题意就不多说了,应该都是很熟悉的了。我是看了《背包九讲》后做的,感觉上面说的很好!

    一:下面这个程序是最基本的,就是没有什么优化的。

    状态转移方程:Div[i][v]=max(Div[i-1][v],Div[i-1][v-w[i]]+c[i]);  

    #include <iostream>
    using namespace std;
    #define MAX 1002
    
    int Div[MAX][MAX];
    int c[MAX];      //价值
    int w[MAX];      //体积
    
    int max(int a,int b)
    {
        if(a>b)
            return a;
        return b;
    }
    
    int main()
    {
        int t,n,v,i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&v);
            memset(Div,0,sizeof(Div));
            for(i=1;i<=n;i++)
                scanf("%d",&c[i]);
            for(i=1;i<=n;i++)
                scanf("%d",&w[i]);
    
            for(i=1;i<=n;i++)
            {
                for(j=0;j<=v;j++)
                {
                    if(j>=w[i])
                        Div[i][j]=max(Div[i-1][j],Div[i-1][j-w[i]]+c[i]);
                    else
                        Div[i][j]=Div[i-1][j];
                }
            }
    
            cout<<Div[n][v]<<endl;
        }
        return  0;
    }
    
    
    

    二:由于时间复杂度已经不能再进行大的优化了。但发现空间使用是很大的,可以在空间上进行优化,既把记录数组Div由二维变成一维,这是可以的。这就是动态数组的思想,因为前面的数组用过之后,就可以用后面的数组去回滚掉!

    动态转移方程:Div[v]=max(Div[v],Div[v-w[i]]+c[i]);

    #include <iostream>
    using namespace std;
    #define MAX 1002
    
    int Div[MAX];
    int c[MAX];      //价值
    int w[MAX];      //体积
    
    int max(int a,int b)
    {
        if(a>b)
            return a;
        return b;
    }
    
    int main()
    {
        int t,n,v,i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&v);
            memset(Div,0,sizeof(Div));
    
            for(i=1;i<=n;i++)
                scanf("%d",&c[i]);
            for(i=1;i<=n;i++)
                scanf("%d",&w[i]);
    
            for(i=1;i<=n;i++)
            {
                for(j=v;j>=w[i];j--)
                {
                    Div[j]=max(Div[j],Div[j-w[i]]+c[i]);
                }
            }
    
            cout<<Div[v]<<endl;
        }
        return  0;
    }
    
    

    三:后来,改了一小下,更好看了一下,但无大用:

    #include <iostream>
    using namespace std;
    #define MAX 1002
    
    int Div[MAX];
    int c[MAX];      //价值
    int w[MAX];      //体积
    
    int main()
    {
        int t,n,v,i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&v);
            memset(Div,0,sizeof(Div));
    
            for(i=1;i<=n;i++)
                scanf("%d",&c[i]);
            for(i=1;i<=n;i++)
                scanf("%d",&w[i]);
    
            for(i=1;i<=n;i++)
            {
                for(j=v;j>=w[i];j--)
                {
                    if(Div[j-w[i]]+c[i]>Div[j])
                        Div[j]=Div[j-w[i]]+c[i];
                }
            }
    
            cout<<Div[v]<<endl;
        }
        return  0;
    }
    
    

    上面的三个程序自我感觉很是可以的,应该没有更好的方法了。希望借此入门,能对DP有些许点了解!

    
    
  • 相关阅读:
    Redis和Memcache的区别分析
    javascript 与jquery为每个p标签增加onclick方法
    repeater单双行颜色不同,gridview repeater DataList 鼠标经过改变背景颜色
    sql 错误提示
    .net获取select控件中的文本内容
    您试图从目录中执行CGI、ISAPI 或其他可执行程序,但该目录不允许执行程序
    html5 调用摄像头
    openfire配置MSSQL说明(数据库设置)
    Openfire 的安装和配置
    JS 等前端学习。
  • 原文地址:https://www.cnblogs.com/silencExplode/p/1870815.html
Copyright © 2011-2022 走看看