最长递增子序列(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;
}