zoukankan      html  css  js  c++  java
  • 算法设计与分析 3.1 小火龙

    ★题目描述

    共有N种商品会进行打折,第i种商品打折后的价格为Ci,原价为Vi,从第Ti天开始出售,每种商品限购一件。

    如果顾客来的时间早于第Ti天,就无法购买到这件商品。

    现在你想知道,倘若你只在第X天带了Y块钱去一次超市,最多可以购买到原价总和为多少的商品。

    ★输入格式

    第一行包括两个正整数N,M,表示有N种商品进行促销,有M个购物询问。

    接下来的N行,每行包括三个正整数Ci, Vi, Ti, 分别表示每种商品的折后价,原价, 和开放购买的日期。

    接下来的M行,每行包括两个正整数Xi和Yi,表示你想知道第Xi天带着Yi去购物最多能买到原价总和多少的商品。

    ★输出格式

    输出包括M行,每行一次整数,表示对应的购物计划所能买的最大原价总和。

    ★样例输入

    5 2
    5 5 4
    1 3 1
    3 4 3
    6 2 2
    4 3 2
    3 8
    5 9
    

    ★样例输出

    10
    12
    

    ★提示

    对于第一个计划,购买第2,3,5种商品收益最高。

    对于第二个计划,购买第1,2,3种商品收益最高。

    对于60%的测试数据,N<=200,M<=1000,Ci,Yi,Vi,Ti,Xi<=300。

    对于100%的测试数据,N<=300,M<=105,Ci,Yi<=109,Vi<=300,Ti,Xi<=300。

    参考大佬的代码

    /*
    动态规划算法
    
    每一次购物询问进行一次动态规划,找出最优解
    
    对商品和询问统一进行排序,按时间升序 
    
    这里考虑数据的大小, Ci,Yi<=109, Vi<=300
    因此将常用的 maxF[i][c] 改为 minF[i][v]
    
    将这个做改变后,要在更新第二遍 
    */
    
    #include<bits/stdc++.h>
    using namespace std;
    
    struct Node{
    	int ti, ci, vi, yi, i, type;
    	Node() {}
    	Node(int c, int v, int t):ci(c), vi(v), ti(t), type(0) {} //输入商品 
    	Node(int x, int y): ti(x), yi(y), type(1) {}//输入询问 
    	bool operator < (const Node &b) const {return ti==b.ti ? type<b.type : ti<b.ti;} //按时间,节点类型升序 
    }node[100301]; 
    
    int Vans=0;
    long F[100000]; //价值 --> 花费
    int res[100001]; 
    
    int main(){
    	int N,M;
    	scanf("%d%d",&N,&M);
    	
    	int c,v,t;
    	for(int i=0; i<N; ++i){
    		scanf("%d%d%d",&c, &v, &t);
    		node[i] = Node(c, v, t); //输入商品
    		Vans += v;
    	}
     	
     	int x,y;
    	for(int i=0; i<M; ++i){
    		scanf("%d%d",&x, &y);
    		node[i+N] = Node(x, y); //输入询问 
    		node[i+N].i = i;
    	}
     	
     	sort(node, node+N+M); //按时间,节点类型升序 
     	
    	memset(F, 0x3f, sizeof(F)); F[0]=0;
    	for(int i=0; i<N+M; ++i){
    		if(node[i].type==0){ //是商品,更新F
    			for(int v=Vans; v>=node[i].vi; --v) F[v] = min(F[v],F[v-node[i].vi]+node[i].ci);
    			for(int v=Vans; v>=0; --v) F[v]=min(F[v], F[v+1]); //重点,再更新一遍。既然花费F[v+1]能获得V+1价值,那么v价值也肯定可以 
    		} 
    		else{
    			res[node[i].i] = upper_bound(F, F+Vans, node[i].yi)-F-1;  //找到此花费下最大价值(F中上界位置v) 
    		}
    	}
    	
    	for(int i=0; i<M; ++i){
    		printf("%d
    ", res[i]);
    	}
    	return 0; 
    }
    
  • 相关阅读:
    多线程案例龟兔赛跑
    不靠谱的事
    生命的价值并不止于自己的幸福
    我的高中搞笑班主任
    AgileChina参会笔记
    上美食
    程序中保留一个Dump
    骗子公司驾到
    我的《野蛮生长》书摘
    最近看的书的清单
  • 原文地址:https://www.cnblogs.com/yejifeng/p/12057429.html
Copyright © 2011-2022 走看看