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;
    }
    	


  • 相关阅读:
    乘法九九表
    #include <time.h>
    【bzoj2060】[Usaco2010 Nov]Visiting Cows拜访奶牛 树形dp
    【codevs1380】没有上司的舞会 树形dp
    【bzoj1060】[ZJOI2007]时态同步 树形dp
    【bzoj2435】[NOI2011]道路修建 树形dp
    【bzoj3573】[HNOI2014]米特运输 树形dp
    【bzoj4027】[HEOI2015]兔子与樱花 树形dp+贪心
    【codevs1163】访问艺术馆 树形dp
    【bzoj1864】[ZJOI2006]三色二叉树 树形dp
  • 原文地址:https://www.cnblogs.com/yyf573462811/p/6365145.html
Copyright © 2011-2022 走看看