码迷,mamicode.com
首页 > 其他好文 > 详细

kuangbin专题-DP

时间:2020-05-30 10:41:17      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:位置   cout   F12   sort   for   maximum   关联   clu   main   

HDU-1024:Max Sum Plus Plus

题意:给m和n和n个数,在n个数里面选取m个互不相交的子段,使他们加和最大,输出最大值,

解:1.在n个数里面选取m段,子问题就可以看成j个数里取i段,就会有状态(i,j),如果推i,dp[j][i]代表从前j个数里取i段,那这和dp[j][i+1]没有特别明显的关联;所以选择推j。

  2.dp[i][j]代表在前j个数中选择i段,那么对于当前j,要么不取、要么和第i段合并、要么单独作为第i段和前i-1段加和。

  3.对于第一种情况,不取的情况,这时的值已经保存在了dp[i][j-1]中,所以不用考虑,那么递推关系式就是dp[i][j]=max(dp[i[j-1],dp[i-1][k])+a[j](i-1<=k<=j-1),

  4.得用滚动数组,将前面的i提出来,用pre保存上一轮前j-1个数的最大值,就改为了dp[j]=max(dp[j-1],pre[j-1])+a[j]

 

技术图片
 1 for(int i=1;i<=m;i++)
 2 {
 3     p=-inf;
 4     for(int j=i;j<=n;j++)
 5     {
 6     dp[j]=max(dp[j-1],pre[j-1])+a[j];
 7     //更新dp[j]后才更新的pre[j-1],因此pre[j-1]中存储的是
 8     //上一轮前j-1个数的i-1段的最大值
 9     pre[j-1]=p;
10     p=max(p,dp[j]);//p来记录最大值
11     }
12 }            
13 //注意最后输出的是p,因为a[n]可能不取,那答案就在前n个dp中
View Code

 HDU-1069:Max Sum Plus Plus

题意:给n块石头的长宽高,每种无限块,垒起来的最高高度,下面的那一块的长宽高都必须绝对大于上面的长宽,

解:1.很容易想到dp[i],代表以第i块石头为底时的最高高度,

  2.因为要绝对大于上面的那一块,所以每种存储三个,x<y,然后排序即可,最后要遍历一遍dp数组取最大值,总是惯性思维感觉最后一个位置的数就是最大的

技术图片
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<stdio.h>
using namespace std;

struct l{
    int x,y,z;
}len[100];
int n;
int ll[3];
int dp[100];

bool cmp(const l &a,const l &b)
{
    if(a.x==b.x) return a.y<b.y;
    else return a.x<b.x;
}

int main()
{
    int t=1;
    while(cin>>n&&n)
    {
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d %d %d",&ll[0],&ll[1],&ll[2]);
            sort(ll,ll+3);
            len[cnt].x=ll[0],len[cnt].y=ll[1],len[cnt].z=ll[2];cnt++;
            len[cnt].x=ll[1],len[cnt].y=ll[2],len[cnt].z=ll[0];cnt++;
            len[cnt].x=ll[0],len[cnt].y=ll[2],len[cnt].z=ll[1];cnt++;
        }
        sort(len,len+cnt,cmp);
        for(int i=0;i<cnt;i++)
        {
            //cout<<len[i].x<<" "<<len[i].y<<" "<<len[i].z<<‘\n‘;
            dp[i]=len[i].z;
        }
        for(int i=0;i<cnt;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(len[j].x<len[i].x&&len[j].y<len[i].y)
                {
                    dp[i]=max(dp[j]+len[i].z,dp[i]);
                }
            }
        }
        int ans=-1;
        for(int i=0;i<cnt;i++) {
            ans=max(ans,dp[i]);
            //cout<<dp[i]<<" ";
        }
        //cout<<"\n";
        //不能输出dp[cnt-1],因为最后一块可能很矮,只能和前面的几块垒起来,使得它不是最优解
        printf("Case %d: maximum height = %d\n",t,ans);
        //cout<<"\n";
        t++;
    }
    return 0;
}
View Code

 

kuangbin专题-DP

标签:位置   cout   F12   sort   for   maximum   关联   clu   main   

原文地址:https://www.cnblogs.com/xxxinnn/p/12990899.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!