POJ - 1948 二维01背包

T了两发,DP方程很简单粗暴

dp[i][j][k]:用前i物品使得容量分别为j和k的背包恰好装满

背包的调用只需一次即可,第一次T就是每次check都丧心病狂地背包一次

对于sum的枚举,其实i j枚举到sum/2就可以了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define scan(a) scanf("%d",&a)
#define rep(i,j,k) for(int i = j; i <= k; i++)
using namespace std;
const int maxn = 1666;

bool F[maxn][maxn];
int len[maxn],n;
double query(double a,double b,double c){
    double p=(a+b+c)/2.0;
    return sqrt(p*(p-a)*(p-b)*(p-c));
}
bool dp[2][maxn][maxn];
int C[maxn],W[maxn],V1,V2;
bool bag(int a,int b){
    V1=a,V2=b;
    rep(i,1,n){
        dp[i&1][0][0]=1;
        rep(j,0,V1){
            rep(k,0,V2){
                dp[i&1][j][k]|=dp[i-1&1][j][k];//not be used
                if(len[i]<=j) dp[i&1][j][k]|=dp[i-1&1][j-len[i]][k];
                if(len[i]<=k) dp[i&1][j][k]|=dp[i-1&1][j][k-len[i]];
            }
        }
    }
    return dp[n&1][V1][V2];
}

#define check(i,j) dp[n&1][i][j]
int main(){
    while(scan(n)!=EOF){
        int sum = 0;
        rep(i,1,n) scan(len[i]);
        rep(i,1,n) sum+=len[i];
        memset(F,0,sizeof F);
        double t=(double)sum/2;
        int tt=sum/2+1;
        int maxi=0,maxj=0;
        rep(i,1,tt){
            rep(j,1,tt){
                if(i+j>t){
                    F[i][j]=1;
                    maxi=i,maxj=j;
                }

            }
        }
        double ans=0;
        bag(maxi,maxj);
        rep(i,1,tt){
            rep(j,1,tt){
                int k = sum-i-j;
                if(F[i][j]&&k>=1&&i+j>k&&i+k>j&&j+k>i&&check(i,j)){
                    ans = max(ans,query(i,j,k));
                }
            }
        }
        long long aans= ans*100;
        printf("%lld\n",aans>0?aans:-1);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/caturra/p/8283164.html

时间: 2024-08-29 23:36:49

POJ - 1948 二维01背包的相关文章

hdu3496 二维01背包

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3496 //刚看题目以为是简单的二维01背包,but,,有WA点.. 思路:题中说,只能买M个光盘,不能多也不能少,所以就要求把背包装满. 恰好把背包装满,那么在初始化时,除了dp[0]=0,剩下的dp[1~M],均为负无穷(其实设置成-1,到时候在判断一下也是一样的,思想相同) 这样才可以保证最终得到的dp[M]是一种恰好装满背包状态的最优解. 代码: #include<iostream

hdu3236Gift Hunting【二维01背包】

Description After winning two coupons for the largest shopping mart in your city, you can't wait inviting your girlfriend for gift hunting. Having inspected hundreds of kinds of souvenirs, toys and cosmetics, you finally narrowed down the candidate l

宠物小精灵之收服 (二维01背包)

[题目链接] http://noi.openjudge.cn/ch0206/4978/ [算法] 做的第一道二维的背包问题,只需开的数组增加一维以正确表述每一个状态即可.本质还是多过程决策+最优子结构+无后效性. [代码] 1 #include <bits/stdc++.h> 2 using namespace std; 3 int n,m,k,i,j,t,minm; 4 int v[1010],u[510],dp[1010][510]; 5 int main() 6 { 7 scanf(&q

poj3260 平衡问题(二维01背包)

http://www.cnblogs.com/ziyi--caolu/p/3228090.html http://blog.csdn.net/lyy289065406/article/details/6648094/ 这道题更加理解了背包问题实质上是状态的转换. 范围中有负数,先平移到全是正数,因为最后所有砝码都要用上,所以可以先遍历第一个的所有情况,再以此推出第二个. 上面的思路用穷举是不行的,所以这时就要用DP,而背包正好很适合解决这一类问题,这就是解题的突破口 #include <iost

POJ2184Cow Exhibition(二维费用背包)

Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9067   Accepted: 3441 Description "Fat and docile, big and dumb, they look so stupid, they aren't much fun..." - Cows with Guns by Dana Lyons The cows want to prove to t

HDU-2159FATE(二维完全背包)

FATE Problem Description 最 近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完 这最后一级.现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度.当忍耐 度降到0或者0以下时,xhd就不会玩这游戏.xhd还说了他最多只杀s只怪.请问他能升掉这最后一级吗? Input 输 入数据有多组,对于每组数据第一行输入

hdu3496+poj1948(二维费用背包)

Watch The Movie Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 5106    Accepted Submission(s): 1614 Problem Description New semester is coming, and DuoDuo has to go to school tomorrow. She dec

HDU 2159 FATE【二维多重背包】

大意:二维多重背包 分析:二维多重背包 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 105; 8 int dp[maxn][maxn]; 9 int a[maxn], b[maxn]; 10 11 int main() { 12 int n,

HDU2159 二维完全背包

FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 12533    Accepted Submission(s): 5932 Problem Description 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级.现在的问