POJ 2392(DP

题意:有K个积木,每个给出块数,高度和这种块不能超过的最大高度,问最高能垒多高。

经历了强行转换语言的阵痛啊。。。。java自定义排序不会写,然后又mle了,让我开始怀疑java的性能(其实只是因为脑残没写滚动数组。。。。)

经典的多重背包,状态是前i种垒到j高时能剩下的第i种块的数目。

import java.util.*;
import java.math.*;
import java.io.*;
public class Main {
    public static final int maxv=2000+40;
    public static void main(String[] args) throws Exception {
        Scanner in = new Scanner(new File("/home/develop/eclipse_file/ACMproject/src/in"));
        // Scanner in=new Scanner(System.in);
        int K=in.nextInt();
        bl[] sc=new bl[K];
        for(int i=0;i<K;i++){
            sc[i]=new bl();
            sc[i].h=in.nextInt();
            sc[i].a=in.nextInt();
            sc[i].c=in.nextInt();
        }
        Arrays.sort(sc);
        int[] dp1=new int[40001];
        int[] dp2=new int[40001];
        int[] swap;
        for(int j=0;j<40001;j++) dp1[j]=-1;
        dp1[0]=0;
        for(int i=1;i<=K;i++){
            for(int j=0;j<40001;j++){
                if(dp1[j]>=0){
                    dp2[j]=sc[i-1].c;
                }else if(j-sc[i-1].h>=0&&dp2[j-sc[i-1].h]>0&&j<=sc[i-1].a){
                    dp2[j]=dp2[j-sc[i-1].h]-1;
                }else{
                    dp2[j]=-1;
                }
            }
            swap=dp1;
            dp1=dp2;
            dp2=swap;
        }
        int ans=0;
        for(int i=0;i<=40000;i++){
            if(dp1[i]>=0) ans=i;
        }
        System.out.println(ans);
        in.close();
    }
}
class bl implements Comparable<bl> {
    int h,a,c;
    @Override
    public int compareTo(bl a){
        return this.a-a.a;
    }
}

时间: 2024-10-27 07:06:11

POJ 2392(DP的相关文章

POJ 2392 Space Elevator(贪心+多重背包)

POJ 2392 Space Elevator(贪心+多重背包) http://poj.org/problem?id=2392 题意: 题意:给定n种积木,每种积木都有一个高度h[i],一个数量num[i],还有一个限制条件,这个积木所在的位置不能高于limit[i],问能叠起的最大高度? 分析: 本题是一道多重背包问题, 不过每个物品的选择不仅仅要受该种物品的数量num[i]限制, 且该物品还受到limit[i]的限制. 这里有一个贪心的结论: 我们每次背包选取物品时都应该优先放置当前limi

HDU 1087 &amp;&amp; POJ 2533(DP,最长上升子序列).

~~~~ 两道题的意思差不多,HDU上是求最长上升子序列的和,而POJ上就的是其长度. 貌似还有用二分写的nlogn的算法,不过这俩题n^2就可以过嘛.. ~~~~ 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1087 http://poj.org/problem?id=2533 ~~~~ HDU1087: #include<cstdio> #include<cstring> #include<algorithm> #

POJ 2392 Space Elevator 背包题解

多重背包,本题不需要二分优化.相对简单点.因为重复数十分小,小于10: 而增加一个限制每种材料的高度做法,如果使用逆向填表,那么只需要从这个高度往小递归填表就可以了. 还有就是注意要排序,以限制高度为标准从小到大排序,否则答案错误的. #include <stdio.h> #include <string.h> #include <algorithm> using std::sort; const int MAX_K = 401; const int MAX_H = 4

POJ 3670 &amp;&amp; POJ 3671 (dp)

最长不下降子序列的应用嘛.两题都是一样的. POJ 3670:求给定序列按递增或递减排列时,所需改变的最小的数字的数目. POJ 3671:求给定序列按递增排列时,所需改变的最小的数字的数目. 思路就是求最长不下降子序列,然后剩下的就是需要改变的字母. 最长不下降子序列:(我之前有写过,不懂请戳)http://blog.csdn.net/darwin_/article/details/38360997 POJ 3670: #include<cstdio> #include<cstring

poj 3783 DP 2个鸡蛋扔100层楼的加强版

http://poj.org/problem?id=3783 估计23号之后的排位赛之后我就要退役了,这之前最后再做5天ACM 今天的排位很惨,上次排位也很惨......这道题原来算法课老师讲过,模模糊糊记得方程,但是边界处理有问题, dp[i][j]=min(1+max(dp[k-1][j-1],dp[i-k][j]))   k=1 to 楼数 dp[i][j]:i层楼扔,手里有j个ball 的次数 边界两个:1.dp[1][i]=1,第一层无论手里有几个鸡蛋都是1次,2.dp[i][1]=i

POJ 3034 DP

打地鼠游戏中,你有一个锤子,每一秒钟你可以拿着锤子移动d个单位的距离,必须是直线,掠过的鼠洞中露出的地鼠都会被锤打至,而事先知道从开始时各时间段内出现在老鼠的数量和位置,问题是从游戏开始至结束时,你最多能打到多少只地鼠,开始时锤子可以在任何位置. 题目有个陷阱, 只是说Moles出现的坐标为正,但没说hammer移动的位置要为正,可以为"any position" 所以锤子可以移出矩阵,再从矩阵外一点移进来 例: 20 5 4 1 0 1 0 1 1 0 5 2 1 6 2 0 0 0

POJ 4968 DP||记忆化搜索

给出N个人的平局分X 根据GPA规则计算可能的最高平均GPA和最低平均GPA 可以DP预处理出来所有结果  或者记忆化搜索 DP: #include "stdio.h" #include "string.h" int inf=100000000; double a[11][1100],b[11][1100]; double Max(double a,double b) { if (a<b) return b; else return a; } double M

POJ 2029 DP || 暴力

在大矩形中找一个小矩形 使小矩形包含的*最多 暴力或者DP  水题 暴力: #include "stdio.h" #include "string.h" int main() { int n,m,w,i,s,t,j,k,l,ans,sum,x,y; int map[101][101]; while (scanf("%d",&w)!=EOF) { if(w==0) break; scanf("%d%d",&n,&

POJ 1160 DP

用数轴描述一条高速公路,有V个村庄,每一个村庄坐落在数轴的某个点上,需要选择P个村庄在其中建立邮局,要求每个村庄到最近邮局的距离和最小. cost记录每两个村庄之间建一个邮局的最小代价. 转移方程: dp[j][i]=Min(dp[j][i],dp[k][i-1]+cost[k+1][j]) 前j个村庄建i个邮局=前k个村庄建I-1个邮局+第k+1村庄到第j村庄建一个邮局的代价 #include "stdio.h" #include "string.h" int i