洛谷Oj-装箱问题-简化的01背包

来源:互联网 发布:细菌觅食优化算法 编辑:程序博客网 时间:2024/06/14 07:56

问题描述
有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
AC代码①(开心的金明稍作修改):

int a[31][3],dp[31][30001];int max1(int a,int b){    return a>b?a:b;}int main(){    int n,m,i,j;    scanf("%d%d",&n,&m);    for(i=1;i<=m;i++)    {        scanf("%d",&a[i][1]);//简化的01背包就是价值=限制,于是将a[i][1]赋给a[i][2]        a[i][2]=a[i][1];    }    for(i=1;i<=m;i++)        for(j=1;j<=n;j++)            if(j>=a[i][1])                dp[i][j]=max1(dp[i-1][j],a[i][2]+dp[i-1][j-a[i][1]]);            else                dp[i][j]=dp[i-1][j];    printf("%d\n",n-dp[m][n]);//打印剩余的最小空间,即总空间减去最大能占据的空间    return 0; 

AC代码②

int a[40];//数组a记录物品的体积bool dp[40][30000];//确定状态:dp[i][j]记录前i个物品能否组成体积j。注意数组不能只开20001!int main(){    int n,m,i,j;    scanf("%d%d",&n,&m);    for(i=1;i<=m;i++)//输入物品的体积        scanf("%d",&a[i]);    dp[0][0]=1;//初始化,即前0个物品能组成体积0,很重要    for(i=1;i<=m;i++)        for(j=0;j<=n;j++)            if(dp[i-1][j]==1)//如果前i-1个物品能组成体积j            {                dp[i][j+a[i]]=1;//那么前i个物品能组成体积j+a[i](放入i)                dp[i][j]=1;//并且前i个物品也能组成体积j(不放入i)            }    for(j=n;j>=1;j--)//倒着判断        if(dp[m][j]==1)        {            printf("%d\n",n-j);            break;        }    return 0; }

算法分析
①简化的01背包就是价值=限制,
②注意初始化

原创粉丝点击