一些DP资料

来源:互联网 发布:南京高新沿江网络问政 编辑:程序博客网 时间:2024/06/05 19:39

最长递增子序列(LIS)

if (a[i]>a[j]) dp[i]=max(dp[i],dp[j]+1)


最长公共子序列(LCS)

dp[i][j]=dp[i-1][j-1]+1 (a[i]==b[j])
dp[i][j]=max(dp[i-1][j],dp[i][j-1])  (a[i]!=b[j])


最长公共子串


dp[i][j]=dp[i-1][j-1]+1 (a[i]==b[j])
dp[i][j]=0 (a[i]!=b[j])


最大连续子序列和

if(dp[i-1]>0) dp[i]=dp[i-1]+a[i]
else  dp[i]=a[i]

数塔

dp[i][j] = max(dp[i+1][j],dp[i+1][j+1])+a[i][j])


凸多边形的三角剖分问题

给定一个N顶点凸多边形,要求把它分成N-2个三角形,使得三角形上顶点权值之积的和最大
状态:dp[i][j]表示从第i到第j点按照最优划分得到的最优值
dp[i][j]=max(dp[i][k]+dp[k][j]+v[i]*v[j]*v[k])(i<k<j)

乘积最大问题

设有一个长度N的数字串,要用K个乘号将它分成K+1部分,找出使总乘积最大的分发
dp[i][j]表示前i位放j个乘号可得的最大乘积
dp[i][j]=max(dp[k][j-1]*digital[k+1][i])(j-1<k<i)
(digital[k+1][i]为数组a[k+1]到a[i]组成的数)

隔板问题:

    for(int i=1;i<=m;i++)        for(int j=1;j<=c;j++)        {            if(i>0&&j>0) dp[i][j]=min(dp[i][j],dp[i-1][j-1]+1);            if(j>0) dp[i][j]=min(dp[i][j],dp[i][j-1]+a[j]-a[j-1]);        }    for(int i=1;i<=m;i++) ans=min(ans,dp[i][c]);


石子合并问题

http://www.cnblogs.com/crackpotisback/p/3851983.html


双机调度问题

n个作业要由两台机器M1和M2加工,必须先在M1上然后在M2上加工,每个作业加工时间分别是ai和bi,求出使加工完成的总时间尽量小的加工顺序
Johnson算法
把作业分成两个集合N1和N2,N1中a<b,N2中a>=b,将N1按a非减序排序,N2按b非增序排序,合并N1、N2


整数被小因数整除的条件


2:末尾是0/2/4/6/8
3:各位数字之和能被3整除
4:末两位组成的数字能被4整除
5:末尾是0/5
6:能被2和3整除
7:将末尾截去,新数+(原末尾*5)能被7整除
8:末三位组成的数字能被8整除
9:各位数字之和能被9整除
10:末尾是0
11:奇位数字之和与偶位数字之和的差能被11整除
12:能被3和4整除
13:将末尾截去,新数+(原末尾*4)能被13整除
17:将末尾截去,新数+(原末尾*5)能被17整除
19:将末尾截去,新数+(原末尾*2)能被19整除


素数筛

#include<stdio.h>#include<stdlib.h>#include<math.h>#include<string.h>#include<algorithm>using namespace std;const int MAXN = 100000;bool sieveflag[MAXN+1]={0,0,1};void sieve(bool sflag[],int n){    for(int i=3;i<=n;i++)    {        sflag[i++]=1;        sflag[i]=0;    }    int m=sqrt(n);    for(int i=3;i<=m;i++)        if(sflag[i])            for(int j=i*2;j<=n;j+=i)                sflag[j]=0;}int main(){    sieve(sieveflag,MAXN);    for(int i=2,num=0;i<=MAXN;i++)    {        if(sieveflag[i])        {            num++;            printf("%d:%d\n",num,i);        }    }    return 0;}

0 0