UVA - 12589 Learning Vector(dp-01背包)

题目:

思路:

dp[j][h]表示选取了j个向量,且高度为h,利用01背包来解决问题。

没选当前的向量:dp[j][h] = dp[j][h];

选了当前的向量:dp[j][h] = dp[j-1][h-p[i].y]+2*p[i].x*(h-p[i].y)+p[i].area;(p[i].area = p[i].x+p[i].y)

代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1000000000
#define mod 1000000007
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int,ll> pii;
const int maxn = 55;
int dp[maxn][maxn*maxn];
int n,k,H;
struct Point{
    int x,y,area;
}p[maxn];

bool cmd(const Point& a,const Point& b){
    return a.y*b.x > a.x*b.y;
}

int main(){//01背包
    //FRE();
    int kase;
    scanf("%d",&kase);
    for(int o=1; o<=kase; o++){
        H = 0;
        scanf("%d%d",&n,&k);
        for(int i=1; i<=n; i++){
            scanf("%d%d",&p[i].x,&p[i].y);
            p[i].area = p[i].x*p[i].y;
            H += p[i].y;
        }
        sort(p+1,p+n+1,cmd);
        memset(dp,-1,sizeof(dp));
        dp[0][0] = 0;
        for(int i=1; i<=n; i++){//枚举所有的向量
            for(int j=k; j>=1; j--){//枚举到向量i时,对k个向量中的值进行更新
                for(int h=H; h>=p[i].y; h--){
                    if(dp[j-1][h-p[i].y]!=-1){
                        dp[j][h] = max(dp[j][h],dp[j-1][h-p[i].y]+(h-p[i].y)*p[i].x*2+p[i].area);
                    }
                }
            }
        }
        int ans=0;
        for(int i=0; i<=H; i++){
            ans = max(ans,dp[k][i]);
        }
        printf("Case %d: %d\n",o,ans);
    }
    return 0;
}

 

posted @ 2019-02-19 10:00  sykline  阅读(218)  评论(0编辑  收藏  举报