zoukankan      html  css  js  c++  java
  • [Uva12260]Free Goodies(dp+贪心)

    解题关键:先对p进行排序,消除p的影响,然后对w进行01背包即可。注意p对w的约束。j<=(cur+1)/2

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    struct node{
        int p,w;
        bool operator<(const node& a)const{
            return p>a.p||(p==a.p&&w<a.w);
        }
    }nod[1002];
    int dp[1002][1002],cost[1002][1002],t,n;
    string s;
    int main(){
        cin>>t;
        while(t--){
            int sum=0;
            memset(dp,0,sizeof dp);
            memset(cost,0,sizeof cost);
            cin>>n>>s;
            for(int i=1;i<=n;i++) cin>>nod[i].p>>nod[i].w,sum+=nod[i].p;
            sort(nod+1,nod+n+1);
            int cur=0;
            for(int i=s[0]=='P'?2:1;i<=n;i++){
                cur++;
                for(int j=1;j<=(cur+1)/2;j++){
                    dp[i][j]=dp[i-1][j];
                    cost[i][j]=cost[i-1][j];
                    if(j!=1&&!dp[i-1][j-1]) continue;
                    if(dp[i][j]<dp[i-1][j-1]+nod[i].w){
                        dp[i][j]=dp[i-1][j-1]+nod[i].w;
                        cost[i][j]=cost[i-1][j-1]+nod[i].p;
                    }else if(dp[i][j]==dp[i-1][j-1]+nod[i].w){
                        cost[i][j]=min(cost[i][j],cost[i-1][j-1]+nod[i].p);
                    }
                }
            }
            cout<<sum-cost[n][(cur+1)/2]<<" "<<dp[n][(cur+1)/2]<<"
    ";
        }
        return 0;
    }

     优化之后:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #define inf 1<<30
    using namespace std;
    typedef long long ll;
    struct node{
        int p,w;
        bool operator<(const node& a)const{
            return p>a.p||(p==a.p&&w<a.w);
        }
    }nod[1002];
    int dp[1002],cost[1002],t,n;
    string s;
    int main(){
        cin>>t;
        while(t--){
            int sum=0;
            memset(dp,0,sizeof dp);
            fill(cost,cost+1001,inf);
            cin>>n>>s;
            for(int i=1;i<=n;i++) cin>>nod[i].p>>nod[i].w,sum+=nod[i].p;
            sort(nod+1,nod+n+1);
            int cur=0;
            cost[0]=0;
            for(int i=s[0]=='P'?2:1;i<=n;i++){
                cur++;
                for(int j=(cur+1)/2;j>=1;j--){//背包容量,每个物品的容量是1
                    if(dp[j-1]+nod[i].w>dp[j]){
                        dp[j]=dp[j-1]+nod[i].w;
                        cost[j]=cost[j-1]+nod[i].p;
                    }else if(dp[j-1]+nod[i].w==dp[j]){
                        cost[j]=min(cost[j],cost[j-1]+nod[i].p);
                    }
                }
            }
            
            cout<<sum-cost[(cur+1)/2]<<" "<<dp[(cur+1)/2]<<"
    ";
        }
        return 0;
    }
  • 相关阅读:
    PCLint
    pthread_join
    作业过程查找
    sqlcmd (转)
    整合问题
    PATINDEX
    回归Dos操作的快感,进入PowerShell世界 (转)
    Javascript 面向对象编程(一):封装
    理解闭包
    Javascript 面向对象编程(三):非构造函数的继承
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7796841.html
Copyright © 2011-2022 走看看