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

动态规划——线性dp

时间:2016-04-16 18:41:18      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:

  我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp。在这篇文章中,我们将讨论有关线性dp的一些问题。

  在有关线性dp问题中,有着几个比较经典而基础的模型,例如最长上升子序列(LIS)、最长公共子序列(LCS)、最大子序列和等,那么首先我们从这几个经典的问题出发开始对线性dp的探索。

  首先我们来看最长上升子序列问题。

  这个问题基于这样一个背景,对于含有n个元素的集合S = {a1、a2、a3……an},对于S的一个子序列S‘ = {ai,aj,ak},若满足ai<aj<ak,则称S‘是S的一个上升子序列,那么现在的问题是,在S众多的上升子序列中,含有元素最多的那个子序列的元素个数是多少呢?或者说这样上升的子序列最大长度是多少呢?

  按照惯有的dp思维,我们将整个问题子问题化(这在用dp思维解决问题时非常重要,基于此各子问题之间的联系我们方能找到状态转移方程),我们设置数组dp[i]表示以ai作为上升子序列终点时最大的上升子序列长度。那么对于dp[i]和dp[i-1],它们之间存在着如下的关系。

  if(ai > ai-1)  dp[i] = dp[i-1] + 1

  else             dp[i] = 1

  这就是最基本的最长上升子序列的问题,我们通过一个具体的问题来继续体会。(Problem source : hdu 1087)

 

Problem Description
Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. Maybe you are a good boy, and know little about this game, so I introduce it to you now.
 
The game can be played by two or more than two players. It consists of a chessboard(棋盘)and some chessmen(棋子), and all chessmen are marked by a positive integer or “start” or “end”. The player starts from start-point and must jumps into end-point finally. In the course of jumping, the player will visit the chessmen in the path, but everyone must jumps from one chessman to another absolutely bigger (you can assume start-point is a minimum and end-point is a maximum.). And all players cannot go backwards. One jumping can go from a chessman to next, also can go across many chessmen, and even you can straightly get to end-point from start-point. Of course you get zero point in this situation. A player is a winner if and only if he can get a bigger score according to his jumping solution. Note that your score comes from the sum of value on the chessmen in you jumping path. Your task is to output the maximum value according to the given chessmen list.
 
Input
Input contains multiple test cases. Each test case is described in a line as follow: N value_1 value_2 …value_N It is guarantied that N is not more than 1000 and all value_i are in the range of 32-int. A test case starting with 0 terminates the input and this test case is not to be processed.
 
Output
For each case, print the maximum according to rules, and one line one case.
 
  题目大意:概括的来讲,就是基于上面给出最长子序列问题的模型,设最长子序列为S‘,而总集S含有n个元素,求出∑ai,其中i∈[1,n]且ai∈S‘,即求最长子序列的和。
  数理分析:有了最原始的最长子序列问题的基础,在这里我们只需要做类似的分析即可。我们设置dp[i]记录以ai为终点的最长子序列的和,我们可以得到如下的状态转移方程。
                                    dp[i] = max{j|dp[j] + ai} ,其中j∈[1,i-1]且aj<ai
  那么完成了对dp[1]到dp[n]的计算,我们只需找到最大值输出即可。
  参考代码如下。
 
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 1005;
const int inf = 999999999;

int a[maxn] , dp[maxn];

int main()
{
       int n , m  , ans;
       while(scanf("%d",&n) && n)
       {
             memset(dp , 0 , sizeof(dp));
             for(int i = 1;i <= n;i++)
                  scanf("%d",&a[i]);

             for(int i = 1;i <= n;i++)
             {
                   ans = -inf;
                   for(int j = 0;j < i ;j++)
                   {
                       if(a[i]>a[j])
                           ans = max(ans , dp[j]);
                   }
                   dp[i] = ans + a[i];
             }

             ans = -inf;
             for(int i = 1;i <= n;i++)
                   ans = max(ans , dp[i]);

             printf("%d\n",ans);
       }
}

 

动态规划——线性dp

标签:

原文地址:http://www.cnblogs.com/rhythmic/p/5398953.html

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