zoukankan      html  css  js  c++  java
  • AtCoder ABC 060 D Simple Knapsack

    背包问题。

    但 w 的范围是1e9 ,显然不能用DP。

    考虑到限制 w1 ≤ wi ≤ w1 + 3,所以最多只会有四个不同的重量,统计每个重量的物品数,

    然后枚举每个重量选多少个物品,选物品时显然要贪心地选最大的。

    代码很丑,也不知道怎么优化

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 110;
    
    int n,cnt;
    ll W,mi,ans;
    int cn[10];
    ll val[10][maxn],w[maxn],cw[maxn],wei[10],v[maxn],pre[10][maxn];
    
    bool cmp(ll a,ll b){
        return a>b;
    }
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
        mi = 1e9 + 7;
        ans = 0;
        n = read(),W = read(); 
        for(int i=1;i<=n;i++){
            w[i] = read(); cw[i] = w[i];
            mi = min(mi, w[i]);
            v[i] = read();
        }
        
        sort(cw+1,cw+1+n);
        
        for(int i = 1;i <= n;i++){
            if(cw[i] != cw[i-1]){
                wei[++cnt] = cw[i];
            }
        }
        
        for(int i=1;i<=n;i++){
            int nt = w[i]-mi+1;
            val[nt][++cn[nt]] = v[i];
        }
        
        for(int i=1;i<=cnt;i++){
            sort(val[i]+1,val[i]+1+cn[i],cmp);
        }
        
        for(int i=1 ;i <= cnt;i++){
            for(int j = 1 ;j<=cn[i]; j++){
                pre[i][j]=val[i][j];
                pre[i][j]+=pre[i][j-1];
            }
        }
        
        if(cnt==4){
            for(int i=0 ;i <= cn[1];i++){
                for( int j= 0;j <= cn[2] ;j++){
                    for( int k=0 ;k <= cn[3] ;k++){
                        for(int p = 0; p <= cn[4] ; p++){
                            if(i*wei[1]+j*wei[2]+k*wei[3]+p*wei[4]<=W){
                                ans =max( pre[1][i] + pre[2][j] + pre[3][k] + pre[4][p],ans);
                            }
                            
                        }
                    }
                }
            }
        }
            
        if(cnt==3){
            for(int i=0 ;i <= cn[1];i++){
                for( int j= 0;j <= cn[2] ;j++){
                    for( int k=0 ;k <= cn[3] ;k++){
                        if(i*wei[1]+j*wei[2]+k*wei[3]<=W){
                            ans =max( pre[1][i] + pre[2][j] + pre[3][k],ans);
                        }
                    }
                }
            }
        }
        
            
        if(cnt==2){
            for(int i=0 ;i <= cn[1];i++){
                for( int j= 0;j <= cn[2] ;j++){
                    if(i*wei[1]+j*wei[2]<=W){
                        ans =max( pre[1][i] + pre[2][j] ,ans);    
                    }
                }
            }
        }
        
        if(cnt==1){
            for(int i=0 ;i <= cn[1];i++){
                if(i*wei[1]<=W){
                    ans =max( pre[1][i] ,ans);
                }
            }
        }
        
        printf("%lld\n",ans);
        
        return 0;
    }
  • 相关阅读:
    深入分析String类型(一)
    创建泛型类
    XML数据的读取—数据库配置文件
    Config配置文件读写
    jQuery动画
    设置屏幕快捷键
    jQuery事件
    jQuery操作DOM
    Python 二进制文件网址
    Centos使用crontab自动定时备份mysql的脚本
  • 原文地址:https://www.cnblogs.com/tuchen/p/13416759.html
Copyright © 2011-2022 走看看