zoukankan      html  css  js  c++  java
  • U33405 纽约

    U33405 纽约

    花费 (w) 元可以购买一辆容量为 (w) 的车
    现在你有 (n <= 2000) 个物品, 搬运策略: 一直搬能放下里面最重的, 直到任意物品都不能搬上为止
    求满足运送次数 (<= R) 的情况下买车花费的最少钱数

    Solution

    二分花钱数, 模拟搬运过程, 复杂度 (O(n^{2}log{n}))
    因为物品排序后有单调性, 且只能用一次(搬一次), 使用链表优化, 总复杂度(O(n log{n}))

    可是这题我认为有问题
    upd: 哦原来后面有说
    问题出在在符合搬运策略的情况下, 出钱数与搬运次数不符合单调性
    所以最后加了个往前面检查多次查看是否合法, 取较小值

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define LL long long
    #define REP(i, x, y) for(int (i) = (x);(i) <= (y);(i)++)
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = 4019;
    int num, R;
    int w[maxn], l[maxn], r[maxn];
    int minn, maxx;
    bool cmp(int a, int b){return a > b;}
    void init(){
    	REP(i, 1, num)l[i] = i - 1, r[i] = i + 1;
    	r[0] = 1;
    	}
    bool check(int k){
    	init();
    	int tim = 0, tot = 0, now = 0, left = num;
    	while(1){
    		now = r[0], tot = 0;
    		tim++;
    		while(now <= num){//运一次
    			if(tot + w[now] <= k){//不超重
    				tot += w[now];
    				r[l[now]] = r[now];//链表删除
    				l[r[now]] = l[now];
    				left--;
    				if(!left){//所有东西搬完检查次数
    					if(tim <= R)return 1;
    					return 0;
    					}
    				}
    			now = r[now];
    			}
    		if(tim > R)return 0;
    		}
    	}
    int search(int l, int r){
    	int ans = -1;
    	while(l <= r){
    		int mid = (l + r) >> 1;
    		if(check(mid))ans = mid, r = mid - 1;
    		else l = mid + 1;
    		}
    	return ans;
    	}
    int ans;
    int main(){
    	num = RD(), R = RD();
    	REP(i, 1, num)w[i] = RD(), minn = min(minn, w[i]), maxx += w[i];
    	sort(w + 1, w + 1 + num, cmp);
    	int temp = search(minn, maxx);
    	for(ans = temp - 51;ans <= temp && !check(ans);ans++);
    	printf("%d
    ", ans);
    	return 0;
    	}
    
  • 相关阅读:
    springboot项目启动成功后执行一段代码的两种方式
    ELK相关资料整理
    Golang指针解析
    Golang文件操作
    Go Channel介绍
    Go语言new和make的区别
    SpringBoot+AOP实现记录操作日志和异常日志,并保存到数据库
    【面试专栏】Java 阻塞队列
    Linux安装Jenkins并构建SpringBoot工程
    Linux安装git
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9747880.html
Copyright © 2011-2022 走看看