zoukankan      html  css  js  c++  java
  • 算法设计与分析 3.3 眯眯眼天使

    ★题目描述

    共有N种商品参与促销。每种物品有价格Ci和原价Vi,以及限购数量Ki。

    店主会在活动当天宣布有一种商品退出促销,无法购买。

    为了获取最大利益,你准备提前计算好Q种情况。

    即在给定携带资金Xi,和无法购买第Yi种物品的情况下,最多能够买走原价总和是多少。

    特别提醒,商品论件出售,不允许拆分。

    ★输入格式

    第一行包括一个正整数N,表示共有N件商品。

    接下来的N行,每行包括三个自然数Ci, Vi, Ki。表示第i件商品的价格、原价和限购数量。

    接下来的一行为Q,表示有Q种可能情况。

    接下来的Q行,每行包括两个自然数Xi, Yi。 表示携带Xi块钱,无法购买第Yi种商品

    ★输出格式

    输出包括Q行,每行包括一个正整数,表示对应的情况下你能买走的最大原价总和。

    ★样例输入

    3
    1 3 1
    1 4 1
    1 5 1
    1
    1 2
    

    ★样例输出

    4
    

    ★提示

    注意,商品编号从0开始。
    对于60%的数据,N=50,Q=20。
    对于100%的数据,1<=N<=800,1<=Q<=50000,1<=Ci,Vi,Ki<=100,0<=Yi<N,0<=Xi<=1000。

    ★参考代码

    思路参考自共享文件

    /*
    该题是一道多重背包问题
    因为本题有禁止购买商品
    所以设立两个数组
    f(i, j) 表示考虑前 i 种商品,花费 j 元能买的最大原件总和。
    g(i, j) 表示考虑后 i 种商品,花费 j 元能买的最大原件总和。
    对于单次询问 x, y,则把x元拆成两个部分(x1、x2)
    前x1元用于买前y-1商品,后x2元用于买后y+1件商品 
    */ 
    #include<bits/stdc++.h>
    using namespace std;
    
    const int M = 1000; //身上带的最多的钱
    int C[800],V[800],K[800];
    int F[801][3001], G[801][3001];
    
    int main(){
    	int N;
    	scanf("%d",&N);
    	for(int i=1; i<=N; ++i) scanf("%d%d%d",&C[i], &V[i], &K[i]);
    	
    	//正序购买商品 
    	memset(F, 0, sizeof(F));
    	for(int i=1; i<=N; ++i){ //考虑第i个商品 
    		for(int k=0; k<=K[i]; ++k){   //第i个商品考虑买k个 
    			for(int c=k*C[i]; c<=M; ++c){  //买该商品花费的钱 
    				F[i][c] = max(F[i][c], F[i-1][c-k*C[i]]+k*V[i]); //产生的最大收益 
    			}
    		}
    		for(int c=1; c<=M; ++c) F[i][c] = max(F[i][c], F[i][c-1]); //更新
    	}
    	
    	//反序购买商品 
    	memset(G, 0, sizeof(G));
    	for(int i=N; i>0; --i){ //考虑第i个商品 
    		for(int k=0; k<=K[i]; ++k){   //第i个商品考虑买k个 
    			for(int c=k*C[i]; c<=M; ++c){  //买该商品花费的钱 
    				G[i][c] = max(G[i][c], G[i+1][c-k*C[i]]+k*V[i]); //产生的最大收益 
    			}
    		}
    		for(int c=1; c<=M; ++c) G[i][c] = max(G[i][c], G[i][c-1]); //更新 
    	}
    
    	int Q,x,y;
    	scanf("%d",&Q);
    	while(Q--){
    		scanf("%d%d",&x, &y); 
    		++y;  //因为商品编号从0开始 
    		
    		int ans=0;
    		for(int c=0; c<=x; ++c){
    			ans = max(ans, F[y-1][c]+G[y+1][x-c]); //第y个商品禁买,花费c买前y-1个商品,花费x-c买后y+1个商品 
    		}	
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    循环队列操作
    让测试人员参与软件设计
    Oracle之初探
    关注LoadRunner脚本回放日志中的Warning信息
    性能测试工具CurlLoader
    『原创』网站测试计划模板
    LoadRunner如何监控Linux下的系统资源
    搭建Linux学习环境安装CentOS5.4
    Linux下搭建Tomcat服务器
    性能测试分析之带宽瓶颈的疑惑
  • 原文地址:https://www.cnblogs.com/yejifeng/p/12060520.html
Copyright © 2011-2022 走看看