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; }