0-1背包 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有些许点了解!



                            

你可能感兴趣的:(HDU)