dp打开思路3:HDU1069 POJ3616 POJ1088
HDU 1069
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1069
题意:把给定的长方体(不限)叠加在一起,叠加的条件是,上面一个长方体的长和宽都比下面长方体的长
和宽短;求这些长方体能叠加的最高的高度.(其中(3,2,1)可以摆放成(3,1,2)、(2,1,3)等).
思路:其实就是求最长的单调递减序列。在长和宽的递减下,求最大能得出的最大高度了。
  
   - 
    
     
    
    
     
      #include<iostream>
     
    
- 
    
     
    
    
     
      #include<cstdio>
     
    
- 
    
     
    
    
     
      #include<algorithm>
     
    
- 
    
     
    
    
     
      #include<cstring>
     
    
- 
    
     
    
    
     
      using namespace std;
     
    
- 
    
     
    
    
     
      struct node
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
      int l,w,h;
     
    
- 
    
     
    
    
     
      }box[111];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      int dp[111];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      bool cmp(node a,node b)//长宽比较函数
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
        if(a.l>b.l) return true;
     
    
- 
    
     
    
    
        if(a.l==b.l&&a.w>b.w) return true;
     
    
- 
    
     
    
    
        return false;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      int main()
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
      int d[3],n,i,j,c=1,k,sumh;
     
    
- 
    
     
    
    
     	while(scanf("%d",&n)!=EOF&&n)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
       k=0;
     
    
- 
    
     
    
    
     		for(i=0;i<n;i++)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
      scanf("%d%d%d",&d[0],&d[1],&d[2]); 
     
    
- 
    
     
    
    
     
      			sort(d,d+3);
     
    
- 
    
     
    
    
     			//将数据转换成多种形式的长方体
     
    
- 
    
     
    
    
     
      			box[k].l=d[2];box[k].w=d[1];box[k].h=d[0];k++;
     
    
- 
    
     
    
    
     
      			box[k].l=d[2];box[k].w=d[0];box[k].h=d[1];k++;
     
    
- 
    
     
    
    
     
      			box[k].l=d[1];box[k].w=d[0];box[k].h=d[2];k++;	 
     
    
- 
    
     
    
    
     
      		} 
     
    
- 
    
     
    
    
     
      		sort(box,box+k,cmp);//长宽排序
     
    
- 
    
     
    
    
     		for(i=0;i<k;i++) dp[i]=box[i].h;//初始化
     
    
- 
    
     
    
    
     		for(i=k-2;i>=0;i--)//跟一维的类似
     
    
- 
    
     
    
    
     			for(j=i+1;j<k;j++)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
      if(box[i].l>box[j].l && box[i].w>box[j].w  && dp[i]<dp[j]+box[i].h)
     
    
- 
    
     
    
    
     
       dp[i]=dp[j]+box[i].h;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      			sumh=dp[0];
     
    
- 
    
     
    
    
     			for(i=0;i<k;i++)
     
    
- 
    
     
    
    
      if(sumh<dp[i]) sumh=dp[i];
     
    
- 
    
     
    
    
     			printf("Case %d: maximum height = %d\n",c++,sumh);
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
        return 0;
     
    
- 
    
     
    
    
     
      }
     
    
 POJ3616
链接:http://poj.org/problem?id=3616
题目大意:
在一个农场里,在长度为N个时间可以挤奶,但只能挤M次,且每挤一次就要休息t分钟;
其实不难,脑子要灵活,只要先对时间排序就好啦。
dp[i]表示i段最大值
  
   - 
    
     
    
    
     
      #include <cstdio>
     
    
- 
    
     
    
    
     
      #include <cstring>
     
    
- 
    
     
    
    
     
      #include <vector>
     
    
- 
    
     
    
    
     
      #include <iostream>
     
    
- 
    
     
    
    
     
      #include <algorithm>
     
    
- 
    
     
    
    
     
      #include <limits.h>
     
    
- 
    
     
    
    
     
      #include <cmath>
     
    
- 
    
     
    
    
     
      #include <queue>
     
    
- 
    
     
    
    
     
      using namespace std;
     
    
- 
    
     
    
    
     
      int dp[10050];
     
    
- 
    
     
    
    
     
      struct sa{
     
    
- 
    
     
    
    
      int x,y,sum;
     
    
- 
    
     
    
    
     
      }p[10050];
     
    
- 
    
     
    
    
     
      int cmp(const sa a,const sa b){
     
    
- 
    
     
    
    
      if(a.x==b.x)
     
    
- 
    
     
    
    
      return a.y<b.y;
     
    
- 
    
     
    
    
      return a.x<b.x;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
     
      int main(){
     
    
- 
    
     
    
    
      int n,m,t;
     
    
- 
    
     
    
    
      scanf("%d%d%d",&n,&m,&t);
     
    
- 
    
     
    
    
      for(int i=0;i<m;i++){
     
    
- 
    
     
    
    
      scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].sum);
     
    
- 
    
     
    
    
     
       p[i].y+=t;
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       sort(p,p+m,cmp);//这一步很关键,时间是有顺序的
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      for(int i=m-1;i>=0;i--){
     
    
- 
    
     
    
    
     
       dp[i]=p[i].sum;
     
    
- 
    
     
    
    
      for(int j=i+1;j<m;j++){
     
    
- 
    
     
    
    
      if(p[j].x>=p[i].y)
     
    
- 
    
     
    
    
     
       dp[i]=max(dp[i],dp[j]+p[i].sum);//转移方程
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
      int maxx=0;
     
    
- 
    
     
    
    
      for(int i=0;i<m;i++)
     
    
- 
    
     
    
    
     
       maxx=max(maxx,dp[i]);
     
    
- 
    
     
    
    
      cout<<maxx<<endl;
     
    
- 
    
     
    
    
      return 0;
     
    
- 
    
     
    
    
     
      }
     
    
 poj1088
http://poj.org/problem?id=1088
当初做的时候死也想不出dp顺序,是脑子太死了,非想着按顺序推,其实按高低排了序就很好搞了。
两种思路:都是从小到大排序。可以以四周为条件更新自己,或者用自己做条件对别人更新。
dp(i,j)表示从点(i,j)出发的最长滑行长度。
排序以后从小到大更新就保证了比它小的一定是正确的最长长度。
第一种思路:周围比它小的里面挑dp最大的,再加一就ok
第二种思路:把周围比它高的点都比较,需要更新就更新。举个例子:if H(i+1,j) > H(i,j) // H代表高度dp(i+1,j) = max(dp(i+1,j),dp(i,j)+1)
文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。
原文链接:fantianzuo.blog.csdn.net/article/details/81811310
- 点赞
- 收藏
- 关注作者
 
             
           
评论(0)