zoukankan      html  css  js  c++  java
  • 关于简单动态规划(Dynamic Programming)的总结

    Instructions

    综上所述(好像没有上)我的DP真的垃圾的一批。。。
    动态规划是用来避免重复计算状态导致效率低的情况,实现动规有记忆化搜索和填表两种方法,但记忆化搜索不能优化空间,所以常用的是填表法。


    下面是几种非常简单的动规经典问题。


    背包问题

    一、0/1背包问题
    每个物品只有一个,考虑选与不选,状态转移方程为f(i,j)=max(f(i-1,j),f(i-1,j-a[i])+w[i])。当然也可以用滚动数组对空间进行优化,倒着循环,状态转移方程为f(j)=max(f(j),f(j-a[i])+w[i])。


    当然关于边界条件,f(i,0)=0,表示第i种物品用0个装0的价值,f(0,j)=-inf,表示不可能的情况,这种就当然不会选到了。
    这个烂东西记忆化搜索才过得去。。。


    二、部分背包问题
    这是个贪心问题,每次选择平均价值最大的装进去。

    void workk(){
    	for(int i=1;i<=n;i++){
    		thi[i].ww=(double)thi[i].w/(double)thi[i].a;
    	}
    	sort(thi+1,thi+n+1);
    	int x=0;
    	for(int i=1;i<=n;i++){
    		x+=thi[i].a;
    		if(x>k){
    			int y=thi[i].a-x+k;
    			anss+=(y*thi[i].ww);
    		}
    		else anss+=(double)thi[i].w;
    		if(x>=k)break;
    	}
    }
    

    三、多重背包
    可以化成0/1背包。


    四、完全背包
    可以化成0/1背包,个数为k/a[i]。


    五、满背包
    状态转移的第二重循环多了必须要>0的限制条件,并且全部初始化为-inf,这样就不会转移到没装满的情况了。

    memset(f,-inf,sizeof(f));
    	f[0]=0;
    	for(int i=1;i<=n;i++){
    		for(int j=c;j>=0&&j>=v[i];j--){
    			f[j]=max(f[j],f[j-v[i]]+p[i]);
    		}
    	}
    

    六、K背包问题
    三重循环,考虑选选与不选,只是每个要选k个。

    memset(f,-inf,sizeof(f));
    	for(int i=0;i<=20000;i++){
    		f2[0][i]=0;
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=k;j>=1;j--){
    			for(int m=c;m>=v[i];m--)
    				f[j][m]=max(f[j][m],f[j-1][m-v[i]]+p[i]); 
    		}
    	}
    

    七、多费用背包
    这个类型的问题有承重和体积两个限制条件,所以状态就是第i种物品在承重为k,体积为j的情况下的价值最大,用滚动数组优化空间,三重循环。


    八、多背包问题
    此类问题就是分别考虑第i个物品装入第一个背包和装入第二个背包的状态。


    LIS和LCS

    关于LIS:最长上升子序列

    设置一个状态数组记录以j结尾的序列里最长上升子序列的长度,最后再取这些状态里的最大值。(n方做法)

    设置一个mark数组,如果当前a[i]>mark[len],那么将mark[len+1]赋值为a[i],否则lower_bound操作返回a[i]的位置,然后把mark[len]赋值为a[i]。这样就能保证字典序最小并且len最大。(nlogn做法)


    关于LCS:最长公共子序列

    把S2这个序列映射成一个新序列,映射的方法是公共元素存成该元素在S1里的序号,非公共元素存成0。然后在新序列上LIS,当然,碰到0的时候跳过就行了。


    序列型动态规划

    一、最大连续和
    设置一个状态数组表示以a[n]结尾的数的最大连续和,再取max,n方。
    二、最长抖动序列
    设置两个状态f,g,表示升序的抖动序列的长度和降序的抖动序列的长度。大于的元素f的转移是max(f(i-1),g(i-1)+1),小于的元素g的转移是g(i)=max(f(i-1)+1,g(i-1))。


  • 相关阅读:
    20155313 杨瀚 《网络对抗技术》实验九 Web安全基础
    20155313 杨瀚 《网络对抗技术》实验八 Web基础
    20155313 杨瀚 《网络对抗技术》实验七 网络欺诈防范
    20155313 杨瀚 《网络对抗技术》实验六 信息搜集与漏洞扫描
    20155313 杨瀚 《网络对抗技术》实验五 MSF基础应用
    20155313 杨瀚 《网络对抗技术》实验四 恶意代码分析
    20155313 杨瀚 《网络对抗技术》实验三 免杀原理与实践
    20155313 杨瀚 《网络对抗技术》实验二 后门原理与实践
    20155313 杨瀚 《网络对抗技术》实验一 PC平台逆向破解(5)M
    20155313 2017-2018-1 《信息安全系统设计基础》课程总结
  • 原文地址:https://www.cnblogs.com/virtual-north-Illya/p/10045324.html
Copyright © 2011-2022 走看看