(1)0-1背包:
如果有一个背包,总载重量为Wt,有n个物品,每个物品重Wi,每个物品价值Ci,那么如何装才能让这个包里面东西的价值最高?
dp[i][j]为前i个物品当中选择装进一个载重量为j的包里最大价值,则:
初始化:dp【0】【x】=0;for i=0-》n;j=0-》Wt
dp[i][j]的值为:dp[i-1][j](第i个物品不装进包里),dp[i-1][j-Wi]+Ci(第i个物品装进包里)的较大者。
(2)有代价的最短路径(动态规划和dijkstra混合使用):
寻求点1到点A之间的最短路,但是每到一个点就会消耗一点钱,这个值用money【i】来表示,钱不够路不通,初始有钱N。
dp【i】【j】为走到第i个点,还剩j钱的最短路径,则:
初始化dp【x】【y】=inf;dp【1】【N-money[1]】=0;ifvisited[x][y]=false;ifVisited[1][N-money[1]]=true;
shortest=inf;
moneyLeft=inf;
number=inf;
while(1){
for(int z=0;z<A;z++)
for(int x=0;x<N;x++){
if(dp[z][x]<number){
shortest=z;
moneyLeft=x;
number=dp[z][x];
}
}
if(shortest==inf)break;
for(int i=0;i<N;i++){
if(ifVisited[i]==false&&g[shortest][i]!=0){
if(moneyLeft>=money[i]&&g[shortest][i]+dp[shortest][moneyLeft]>dp[i][moneyLeft-money[i]]){
dp[i][monetLeft-money[i]]=dp[shortest][moneyLeft]+g[shortest][i];
}
}
}
}
result=max(dp[A][x]);
(3)划分DP:
一个m位数,将其分成n部分,要求这n部分乘积最大,求分法。
规定a【i】【j】代表从第i位到j位这个数
并且,dp【i】【j】代表前i个数,分成k部分的最大积
那么,dp【i】【j】=dp【x】【k-1】*a【x+1】【j】的最大值,x从0到j-1
初始化的时候,需要把dp【x】【1】初始化为a【1】【x】
__int64 number;
//初始化a数组
for(int i=1;i<m;i++){
a[i][i]=number%10;
number/=10;
}
for(int i=1;i<m;i++){
for(int j=i+1;j<=m;j++){
a[i][j]=a[i][j-1]*10+a[j][j];
}
}
//进行规划
初始化dp后:
for(int j=1;j<=n;j++){
for(int i=j;i<=m;i++){
for(int k=1;k<=i;k++){
dp[i][j]=max(dp[i][j],dp[k][j-1]*a[k+1][j]);
}
}
}
(4)凑数
假设有几种整数:1,2,4。。。。。。请你用这些数凑一个整数N,要求用的数的数量最少,每种数可以多次使用
dp【i】代表凑数字i所需要用到的最小数量,那么
dp【i】=dp【i-1】到dp【i-2】到dp【i-4】的最小值加1.
(5)装配线调度。
有两个装配线,1号,2号,每个线有N个装配流程,一个产品要生产,必须走完这N个流程,但是每个流程要在1号或2号线装配是都可以的,每个流程所需时间为Cij,产品每进入一个其他的装配线(一开始不在装配线上,进入也算进入其他的装配线),需要消耗的时间为TIMEij,i代表第i条线,j代表第j个流程,求走完全部装配线最小时间。
dp【i】【j】代表在第i条线完成第j个流程所需最小时间。
则dp【1】【j】=min(dp【1】【j-1】+C1j,dp【2】【j-1】+TIME1j+C1j)
(6)序列S和T之间的距离定义:删除,修改,增加一个字符距离+1,最小的距离就是ST之间的距离,求ST之间最小距离:
dp【i】【j】代表S前i个T前j个的最小距离
则dp【i】【j】=min(dp【i-1】【j-1】+(s[i]==t[j])?0:1,dp【i-1】【j】+1,dp【i】【j-1】+1)
(7)最长公共子序列
当i==j dp【i】【j】=dp【i-1】【j-1】+1
如果i!=j,则dp【i】【j】=max(dp【i】【j-1】,dp【i-1】【j】)
回溯法求子序列:
while(unfinished){
if(s[i]=t[j]) push(s[i]); i–;j–;
else if(dp[i-1][j]大) i–,否则j–;
}
(8)最大子序列
dp【i】=(dp【i-1】>0?)dp【i-1】+string【i】:string【i】
(9)最长递增子序列
dp【k】代表前k个数字的最长,包含k
如果number【k】>number【k-1】,则dp【k】=dp【k+1】+number【k】
否则,向前寻找到第倒数第一个比k小的,比如是第A个,则dp【k】=max(dp【A】+number【k】)