zoukankan      html  css  js  c++  java
  • 动态规划

    动态规划(Dynamic Programming)是是运筹学的一个分支,是求解决策过程最优化的数学方法。 动态规划被用于解决多阶段最优化决策问题。它的基本思路是将待解决的问题划分成多个阶段,每个阶段可能存在多种不同的状态。如果划分阶段后的问题满足最优子结构,则可以用动态规划算法一个阶段一个阶段,一个状态一个状态地解决问题的所有子问题,继而解决原问题。(罗嗦的概念)

    动规分为几部分

    阶段

    阶段的划分是人为的。但是必须满足在一个阶段的任意状态做出任何决策后,得到的新状态都属于之后的阶段。(甚至不能在原阶段停留) 不过实际问题中,有的时候阶段并不是线性的,有的时候你很难描述阶段,但是实际上阶段只是提供了一个解决问题的顺序和设计状态的思路,设计出合理高效的状态才是解决问题的关键。 即:阶段的最大作用是辅助状态设计。

    状态

    到达某个过程,处于某个状态。一个状态是一个事件,并且包含一切会对决策产生影响的限制条件。

    子问题

    把一个大的问题化为越来越简单的子问题,通过状态转移方程对大问题求解。子问题与原问题非常相似,或者说根本就是同一个问题,相同的限制条件,相同的最终目的,只是改变了问题的规模,而解决问题需要的方法,也许可以完全仿照原问题。看到这里,你想到了什么?递归!搜索!

    决策

    决策是一个集合。不同的状态可能有不同的决策集合。但是同一个状态一定有相同的决策集合。

    转移

    转移用来描述两个子问题之间的关系,A子问题对应的状态进行决策C能到转化为B子问题,称为A→B有C转移。

    废话不多说看题(虽然说了不少

    1258:【例9.2】数字金字塔


    时间限制: 1000 ms         内存限制: 65536 KB
    提交数: 11942     通过数: 6782 

    【题目描述】

    观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以从当前点走到左下方的点也可以到达右下方的点。

    在上面的样例中,从13到8到26到15到24的路径产生了最大的和86。

    【输入】

    第一个行包含R(1≤ R≤1000),表示行的数目。

    后面每行为这个数字金字塔特定行包含的整数。

    所有的被供应的整数是非负的且不大于100。

    【输出】

    单独的一行,包含那个可能得到的最大的和。

    【输入样例】

    5
    13
    11 8
    12 7  26
    6  14 15 8
    12 7  13 24 11

    【输出样例】

    86
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int a[1001][1001],f[1001][1001];
    int main()
    {
    	int n;
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=i;j++)
    		cin>>a[i][j];
    	 }
    	for(int i=n;i>=1;i--)
    	{
    		for(int j=1;j<=i;j++)
    		f[i][j]=max(f[i+1][j],f[i+1][j+1])+a[i][j]; //状态转移方程不难看懂
    	 } 
    	 cout<<f[1][1];
    }

    1259:【例9.3】求最长不下降序列


    时间限制: 1000 ms         内存限制: 65536 KB
    提交数: 14765     通过数: 4732 

    【题目描述】

    设有由n(1n200)n(1≤n≤200)个不相同的整数组成的数列,记为:b(1)b(2)b(n)b(1)、b(2)、……、b(n)若存在i1<i2<i3<<iei1<i2<i3<…<ie 且有b(i1)b(i2)b(ie)b(i1)≤b(i2)≤…≤b(ie)则称为长度为e的不下降序列。程序要求,当原数列出之后,求出最长的不下降序列。

    例如13,7,9,16,38,24,37,18,44,19,21,22,63,15。例中13,16,18,19,21,22,63就是一个长度为7的不下降序列,同时也有7 ,9,16,18,19,21,22,63组成的长度为8的不下降序列。

    【输入】

    第一行为n,第二行为用空格隔开的n个整数。

    【输出】

    第一行为输出最大个数max(形式见样例);

    第二行为max个整数形成的不下降序列,答案可能不唯一,输出一种就可以了,本题进行特殊评测。

    【输入样例】

    14
    13 7 9 16 38 24 37 18 44 19 21 22 63 15

    【输出样例】

    max=8
    7 9 16 18 19 21 22 63
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int a[201],f[201],c[201];
    int main()
    {
    	int n,maxx=0xc0c0c0c0;
    	int k;
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	f[i]=1;
    	for(int i=1;i<=n;i++)
    	cin>>a[i];
    	for(int i=2;i<=n;i++)
    		for(int j=1;j<i;j++)
    		{
    			if(a[i]>=a[j])
    				if(f[i]<f[j]+1)
    					f[i]=f[j]+1;
    		} 
    	for(int i=1;i<=n;i++)
    			if(f[i]>maxx)
    			{
    				maxx=f[i];
    				k=i;
    			}
    	cout<<"max="<<maxx<<endl;
     	int q=1,m=maxx,ii=k-1;
        c[1]=k;
        while(m>1)
        {
            if(f[ii]==m-1&&a[ii]<=a[k])
            {
                c[++q]=ii;
                k=ii;
                m--;
            }
            ii--;
        }
        for(ii=q;ii>0;ii--)
            printf("%d ",a[c[ii]]);
    }
     
  • 相关阅读:
    Linux 下安装JDK1.8
    INSERT IGNORE 与INSERT INTO的区别
    linux安装redis 完整步骤
    从0开始 图论学习 广度优先搜索 链式前向星表示法
    从0开始 图论学习 深度优先遍历 链式前向星表示法
    从0开始 图论学习 链式前向星 最好的建图方法
    从0开始 图论学习 邻接表 STL vector
    从0开始 图论学习 前向星表示法
    数据结构实习
    数据结构实习
  • 原文地址:https://www.cnblogs.com/zhaoxuelin/p/12403826.html
Copyright © 2011-2022 走看看