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


  • 相关阅读:
    矩阵构造方法(转载)
    欧拉函数
    POJ3233:Matrix Power Series(矩阵快速幂+二分)
    矩阵快速幂(转载)
    素数筛法模板
    快速幂取模算法
    hdu1286(找新朋友)&&POJ2407Relatives(欧拉函数模版题)
    判断两线段相交
    POJ3070:Fibonacci(矩阵快速幂模板题)
    HDU1575:Tr A(矩阵快速幂模板题)
  • 原文地址:https://www.cnblogs.com/yyf573462811/p/6365145.html
Copyright © 2020-2023  润新知