• 动态规划


     

    最长连续子数列和

    -2 6 -1 5 4 -7 2 3

    求连续的子数列最大和。

    根据递归的思路想:f(n) = max{ f(n-1) + num[n], num[n] }

     

     

    hdu1506 Largest Rectangle in a Histogram

    对于每一个高度h[i],搜索它能到达的最左,和最右,最大面积Smax = Max{ i | 面积Si = (最右 - 最左 + 1) *h[i] }

    这样的时间复杂度为O(n^2),必超时

    举例 2,3,4,5

    要判断2能到达最右的位置,不需要循环比较,只需要知道3能到达的最右是哪里,因为若3能到达的位置,2必然也能到达

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int n;
     8     while(scanf("%d", &n) && n)
     9     {
    10         long long h[100007];
    11         long long l[100007];
    12         long long r[100007];
    13         for(int i=1;i<=n;i++)
    14         {
    15             scanf("%lld", &h[i]);
    16             l[i] = r[i] = i;
    17         }
    18         h[0] = h[n+1] = -1;
    19         for(int i=1;i<=n;i++)
    20         {
    21             while(h[i] <= h[l[i]-1]) {
    22                 l[i] = l[l[i]-1];
    23             }
    24         }
    25         for(int i=n;i>=1;i--)
    26         {
    27             while(h[i] <= h[r[i]+1]) {
    28                 r[i] = r[r[i]+1];
    29             }
    30         }
    31         long long ans = 0;
    32         for(int i=1;i<=n;i++)
    33         {
    34             ans = ans > (r[i]-l[i]+1)*h[i] ? ans : (r[i]-l[i]+1)*h[i];
    35         }
    36         printf("%lld
    ",ans);
    37     }
    38 }
    View Code

    LeetCode 338. Counting Bits

    第一道自己做出来的DP!!!纪念合影,你没听错我就是这么菜

    给你一个非负整数num,求从0到num的num+1个数中,每个数二进制表示的1的个数,返回一个数组

    就是dp嘛,暴力的办法就是for from 0 to num,每个数的每一个二进制位比较,设二进制位最坏长度为31位,那么复杂度就是O(31*n)

    其中大量重复计算,所以用动态规划解决,自底向上

     1 class Solution {
     2 public:
     3     vector<int> countBits(int num) {
     4         vector<int>dp(num+1);
     5         dp.resize(num+1);
     6         dp[0] = 0;
     7         for(int i=1;i<=num;i++)
     8         {
     9             if((i & 1) == 0)
    10                 dp[i] = dp[i>>1];
    11             else
    12                 dp[i] = dp[i>>1] + 1;
    13         }
    14         return dp;
    15     }
    16 };
    View Code

    非连续最大子集

    给你一个序列arr = {}

    请你求出它的一个子集,要求,子集和最大,且子集的元素在原序列终不能相邻

    入门DP

    对于每一个数,dp[i] = max{ dp[i-1], dp[i] + arr[i-1] }

    那么就和斐波那契有点像了

    能不能组成S?

    给你一个序列arr = {},和一个数S,问你序列里的数能不能组成S

    又是简单的选和不选问题

    web数据挖掘中的编辑距离

    这个有点难想,参考链接

    稍微变了一小下的01背包

    uim拉着基友小A到了一家……餐馆,很低端的那种。

    uim指着墙上的价目表说:“随便点”。

    题目描述

    不过uim由于买了一些,口袋里只剩M元(M10000)。

    餐馆虽低端,但是菜品种类不少,有N(N100),第i种卖a(ai1000)。由于是很低端的餐馆,所以每种菜只有一份。

    小A奉行“不把钱吃光不罢休”,所以他点单一定刚好吧uim身上所有钱花完。他想知道有多少种点菜方法。

    思路:和裸的价值+容量的01背包不同,原来是求可放入背包且价值最大化,这个是必须装满背包,求有多少种方案。

    根据题意设数组dp[i][j]为前i种菜品恰好花费j元的点菜方法数。那么,考虑第i种菜点或不点,若不点,则说明前i-1种菜,已经恰好花费j元;若点,则说明前i-1种菜,花费j-ai元,这样,在点完第i种菜后,恰好花费j元。

    因此容易得出公式

    dp[i][j] = dp[i-1][j] + dp[i-1][j-ai]

    然而很多人想到这里以后就不知道接下来怎么做了。(比如说我)

    但是在看到"j - ai"后,应该能想到,对j - ai的情况进行枚举。

    若j > ai,则和上式一样。

    若j < ai,则说明第i道菜,压根就买不起,因此dp[i][j] = dp[i-1][j]。

    若j == ai,那么说明可以只点这一道菜作为一种新的方案,dp[i][j] = dp[i-1][j] + 1。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 using namespace std;
     5 
     6 int dp[103][10003] = {0};
     7 int price[103];
     8 
     9 int main()
    10 {
    11     int n, m;
    12     scanf("%d%d", &n, &m);
    13     for(int i=1;i<=n;i++) {
    14         scanf("%d", &price[i]);
    15     }
    16     for(int i=1;i<=n;i++) {
    17         for(int j=1;j<=m;j++) {
    18             if (j == price[i])
    19                 dp[i][j] = dp[i-1][j] + 1;
    20             else if (j > price[i])
    21                 dp[i][j] = dp[i-1][j] + dp[i-1][j - price[i]];
    22             else
    23                 dp[i][j] = dp[i-1][j];
    24         }
    25     }
    26     printf("%d
    ", dp[n][m]);
    View Code
  • 相关阅读:
    ES6中的解构赋值
    一·京京得水
    localStorage,sessionStorage和cookie的区别
    mondodb和mysql的区别
    Win10 x64连接Oracle
    JFinal项目实践(了如股掌)7
    JFinal项目实践(了如股掌)6
    JFinal项目实践(了如股掌)5
    JFinal项目实践(了如股掌)4
    JFinal项目实践(了如股掌)3
  • 原文地址:https://www.cnblogs.com/liwenchi/p/8335133.html
Copyright © 2020-2023  润新知