zoukankan      html  css  js  c++  java
  • hdu 3449 Consumer(DP)

    点击打开链接

    题目;依赖背包。。

    购物,买相应物品时,必须先买其对应的箱子。。以及n个盒子的价钱和,该盒子中所可以装的物品的价格和价值。

    求最大价值!!

    一般的:

    dp[i][j]=dp[i][j-cost[i]]+value[i];

    但需要考虑盒子的价值。故

    dp[i][j]=max(dp[i-1][j],max(dp[i-1][j-k]+pack[i][k]));

    其中dp[i][j]表示使用前i个盒子,花费j所得到的最大价值;考虑第i个盒子到底选不选以及选的话,该多花多少钱,很明显时间复杂度高,故优化;

    仔细分析会发现dp[i-1][j-k]+pack[i][k]是在考虑第i个盒子的情况下的最大价值;

    将盒子的价值当做0,在金钱j下,首先将盒子的价钱考虑进去,那么剩下的只是挑选盒子中的物品,即01背包;

    令f(i,j)为前i个盒子且第i个一定考虑在内的情况下的最大价值,所以初始化为f(i,j)=max(f[i][j-box[i]]+0)(PS:初始化后,盒子的影响就没有了);之后01就可以了!

    #include"stdio.h"
    #include"string.h"
    #define max(x,y) x>y?x:y;
    int dp1[100001];
    int dp2[100001];
    int main()
    {
    	int n,w,i,j,k;
    	int cost[55][11],value[55][11];
    	int num[55],box[55];
    	while(scanf("%d%d",&n,&w)!=-1)
    	{
    		for(i=1;i<=n;i++)
    		{
    			scanf("%d",&box[i]);
    			scanf("%d",&num[i]);
    			for(j=1;j<=num[i];j++)
    				scanf("%d%d",&cost[i][j],&value[i][j]);
    		}
    		memset(dp1,0,sizeof(dp1));
    		for(i=1;i<=n;i++)
    		{
    			for(j=w;j>=box[i];j--)
    				dp2[j]=dp1[j-box[i]];//初始化,消除盒子的影响!!
    			for(j=1;j<=num[i];j++)
    			{
    				for(k=w;k>=cost[i][j]+box[i];k--)
    					dp2[k]=max(dp2[k],dp2[k-cost[i][j]]+value[i][j]);
    			}
    			for(j=w;j>=box[i];j--)
    				dp1[j]=max(dp1[j],dp2[j]);//更新dp1
    		}
    		printf("%d\n",dp1[w]);
    	}
    	return 0;
    }
    	


  • 相关阅读:
    无锁队列的实现
    C/C++语言中闭包的探究及比较
    Linus:利用二级指针删除单向链表
    Unix考古记:一个“遗失”的shell
    “C++的数组不支持多态”?
    Alan Cox:单向链表中prev指针的妙用
    二叉树迭代器算法
    C语言全局变量那些事儿
    数据即代码:元驱动编程
    C++模板”>>”编译问题与词法消歧设计
  • 原文地址:https://www.cnblogs.com/yyf573462811/p/6365145.html
Copyright © 2011-2022 走看看