Onway

我是一只菜菜菜菜鸟...
posts - 61, comments - 56, trackbacks - 0, articles - 34

HDU 2159 FATE 二维费用的背包

Posted on 2010-08-05 22:37 Onway 阅读(842) 评论(2)  编辑 收藏 引用 所属分类: 伤不起的ACM

HDU 2159 FATE 二维费用的背包

在pku用二维费用重做了一次1882以后,发现这个题其实也挺简单的。

先说一下pku1882,第一个费用是张数,第二个费用是与价值等同的重量,即题中的面值。

可以设计状态为f[i][j]表示用到第i张邮票组成面值为j时能获得的最大价值,即能组成最大的面值(<=j)。然后是转化为完全背包来做,循环顺序由低到高。

然后hdu 2159比pku 1882好处理,要处理的数据比较少。不同的是,二维费用改变了,背包状态的设计也改变了。

设f[i][j]表示杀到第i个怪,忍耐度在j的时候能获得的最大价值。注意这样设计状态的话,开的数组不用很大。我是数组开小了,贡献了一次RE,很厚道,报的是RE,如果是WA,就难受了。

这样设计状态,在后面查找结果的时候要对j进行一次历遍查找。

#include <iostream>
using namespace std;
int data[101][2],exp[101][101];
int fmax(int a,int b)
{
return a>b?a:b;}
int main()
{
    
int rem,bear,kind,kill;
    
while(scanf("%d%d%d%d",&rem,&bear,&kind,&kill)!=EOF)
    {
        
int i,j,k;
        
for(i=1;i<=kind;++i)
            scanf(
"%d%d",&data[i][0],&data[i][1]);

        memset(exp,
0,sizeof(exp));
        
for(i=1;i<=kind;++i)
            
for(j=1;j<=kill;++j)
                
for(k=data[i][1];k<=bear;++k)
                    exp[j][k]
=fmax(exp[j][k],exp[j-1][k-data[i][1]]+data[i][0]);

        
for(i=kill,j=1;j<=bear;++j)
            
if(exp[i][j]>=rem)
                
break;
        
if(j>bear)
            printf(
"%d\n",-1);
        
else
            printf(
"%d\n",bear-j);
    }
    
return 0;
}

Feedback

# re: HDU 2159 FATE 二维费用的背包  回复  更多评论   

2011-05-31 20:23 by sleeper
个人感觉这个二维完全背包是错误的,只能说HDU的数据太水。
for(i=1;i<=kind;++i)
for(j=1;j<=kill;++j)
for(k=data[i][1];k<=bear;++k)

在这个最为关键的三重循环中,最后一个循环应该还是顺序,
可以同样用完全背包与0-1背包的区别去思考这个问题,

# re: HDU 2159 FATE 二维费用的背包  回复  更多评论   

2011-08-11 11:02 by Lvsi
for(i=kill,j=1;j<=bear;++j)
if(exp[i][j]>=rem)
break;
这里j从0开始更好吧。。。 否则0 1 1 1 这种测试数据过不了的。。。。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理