zoukankan      html  css  js  c++  java
  • CodeForces

    CodeForces - Problem 1446 - Knapsack - 思维

    对于所有物品按照重量从小到大排序,然后从后向前遍历:

    • 对于重量已经超过了(omega)的物品,将其忽略掉;
    • 对于重量处于([lceil frac{omega}{2} ceil,omega])的物品(如果存在),则直接选取这个物品,输出答案
    • 对于所有重量小于(lceil frac{omega}{2} ceil)的物品,从大到小取物品,直到取完.如果中途发现累计重量处于([lceil frac{omega}{2} ceil,omega]),输出答案; 如果取完时重量仍小于(lceil frac{omega}{2} ceil),输出不存在.

    本题思维主要在于第三条: 当我们从所有重量处在([lceil frac{omega}{2} ceil,omega])的物品中挑选时:先去重量最大的物品,其重量处于((0,lceil frac{omega}{2} ceil)),接下来再取次大的,由于两个物品重量都处于((0,lceil frac{omega}{2} ceil)),因此重量和不会超过(omega); 此时判断累计重量是否处于([lceil frac{omega}{2} ceil,omega]),如果仍然不是,说明累计重量处于((0,lceil frac{omega}{2} ceil)),那么再取第三个物品后累计重量仍然不会超过(omega),这样以此类推,我们优先选择重量大的,所得到的累计重量就会尽可能地大而又不超过(omega),这样做显然符合题意;

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 2e5+5;
    struct node{
        ll v;
        int p;
    };
    node a[N];
    int ans[N]; int len;
    bool comp(const node&a,const node&b){
        return a.v < b.v;
    }
     
    int find_begin(int n,ll w){
        int l = 1, r = n;
        while(l < r){
            int mid = l+r>>1;
            if(a[mid].v >= w){
                r = mid;
            }else{
                l = mid+1;
            }
        }
        return l;
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            len=0;
            int n;
            ll w;
            scanf("%d%lld",&n,&w);
            for(int i = 1; i <= n; i++){
                scanf("%lld",&a[i].v);
                a[i].p = i;
            }
     
            sort(a+1,a+1+n,comp);
     
            int p = find_begin(n,(w+1)/2);
            int ptr = 0;
            if(a[p].v > w){
                ptr = p-1;
            }else if(a[p].v <= w && a[p].v >= (w+1)/2){
                printf("1
    %d
    ",a[p].p);
                continue;
            }else{
                ptr = p;
            }
            int flag = 0;
            ll sum = 0;
            for(int i = ptr; i >= 1; i--){
                if(sum + a[i].v <= w){
                    sum += a[i].v;
                    ans[++len] = a[i].p;
                }
     
                if(sum >= (w+1)/2){
                    flag = 1;
                    break;
                }
            }
     
            if(flag){
                sort(ans+1,ans+1+len);
                int first = 1;
                printf("%d
    ",len);
                for(int i = 1; i <= len; i++){
                    if(first)first=0;else putchar(' ');
                    printf("%d",ans[i]);
                }
                putchar('
    ');
            }else{
                printf("-1
    ");
            }
        }
     
        // system("pause");
        return 0;
    }
    
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解
    大型网站系统架构技术原理透析
    大中型网站架构探秘
    大型网站架构不得不考虑的10个问题
    (推荐)高并发高流量网站架构详解
    可扩展、高可用、负载均衡网站架构设计方案
    nginx内置常用变量
    Linux下nginx支持.htaccess文件实现伪静态的方法!
    扩展js,实现c#中的string.format方便拼接字符串
    Winform退出运行后,删除运行目录(批处理方法)
  • 原文地址:https://www.cnblogs.com/popodynasty/p/13992875.html
Copyright © 2011-2022 走看看