dp小结
来源:互联网 发布:java snmp4j get超时 编辑:程序博客网 时间:2024/06/05 17:04
建模思想
给dp[i][j]一个定义(i和j可能会有一定的关系,例如i<j)
再对具体某个dp[i][j]进行观察(可以借助于表格等),找出它可以由哪些已知的dp[][]经过一定的处理得到,并对这些解进行比较,得出最优解。
列出状态转移方程。
对dp初始化,再根据状态转移方程算出所有dp。
常用的状态转移方程
记忆化搜索dfs;
dp[i]=最优解{dp[j]+cost[j][i]} (0<j<i)
dp[i][j]为前j个地点取i个的最优解
dp[i][j]=最优解{dp[i-1][k]+cost[k+1][j]} i-1<=k<j二维dp的横坐标和纵坐标可能是不同的状态,取其最优解一般会有n个操作,至于dp[i][j]具体的值一般为所求值。(怎么这么像背包啊?!)
dp[i][j]=最优解(dp[i-t][j-q[k].v]+q[k].w) (0<k<n,t一般为1)表格dp[i][j]= 最优解{dp[i-1][j],dp[i][j-1],dp[i-1][j-1]+1}
间隔dp[i]=最优解{dp[i-1],dp[i-2]+v[i]};
矩阵,dp:化为一维,left[i],right[i];
注意
找规律的一些dp可以把完整的一遍先算完,避免TLE。例HUD 1502
常见类型
记忆化搜索
int dfs(int S){ if(dp[S]!=-1) return dp[S]; //记得初始化为-1 dp[S]=-1<<30; int i; for(i=1;i<=n;i++) { if(S>=v[i]) { if(dp[S]<dfs(S-v[i])+w[i]) { dp[S]=dfs(S-v[i])+w[i]; } } } return dp[S];}
最大连续子序列
跟前一个比较,sum<0从头开始记,不然++
代码
sum=0; for (i=0;i<n;i++) { if (sum<0) sum=a[i]; else sum+=a[i]; }
最长公共子序列
dp jpeach 012345i0000000a1000111p2011111p3011111l4011111e5012222dp[i][j]= max(dp[i-1][j],dp[i][j-1])dp[i][j]= max[dp[i][j], dp[i-1][j-1]+1,(str1[i]==str2[j])]
找出最长公共子序列(回溯)
int k=0;char q[110];int i=strlen(str1);int j=strlen(str2);while(i!=0||j!=0){ if(i==0) q[k++]=str2[j--]; //str2还有多 else if(j==0) q[k++]=str1[i--]; //str1还有多 else if(dp[i][j]==dp[i][j-1]) q[k++]=str2[j--]; //从左边取值 else if(dp[i][j]==dp[i-1][j]) q[k++]=str1[i--]; //从右边取值 else if(dp[i][j]==dp[i-1][j-1]+1) //从左上角取值 { q[k++]=str1[i--]; j--; }}
最长上升子序列
常规做法
for(i=0;i<n;i++){ int max=0; for(j=0;j<i;j++) { if(v[i]>v[j]&&dp[i]<dp[j]+1) dp[i]=dp[j]+1; }}
优化
int dp[MAXN]; //dp长度,dp[i]为当前i长度最小的v[k];for(i=1;i<n;i++){ l=1;r=len; while(l<=r) //二分找到v[i]最优位置 { mid=(l+r)/2; if(dp[mid]<v[i]) l=mid+1; else r=mid-1; } dp[l]=v[i]; //更新dp[l]; if(l>len) len++; //增加长度}
最长公共递增子序列
n^2做法
int temp=0; for(i=1;i<=n;i++) { for(temp=0,j=1;j<=m;j++) { if(v1[i]>v2[j]&&dp[j]>temp) temp=dp[j]; if(v1[i]==v2[j]) dp[j]=temp+1; } } temp=0; for(i=1;i<=m;i++) temp=max(dp[i],temp);
dp==lr
for(i=1;i<=n;i++) { while(v[l[i]-1]>=v[i]) l[i]=l[l[i]-1]; } for(i=n;i>=1;i–-) { while(v[r[i]+1]>=v[i]) r[i]=r[r[i]+1]; }
0 0
- dp小结
- dp小结
- dp小结
- DP小结
- dp小结
- dp 小结
- dp小结
- dp小结
- 树形dp小结
- 概率DP小结
- 数位DP小结
- 数位DP小结
- 树形DP小结
- 基础概率DP小结
- 基础数位DP小结
- 区间dp小结
- DP优化小结
- 基础树形DP小结
- C++语言的15个晦涩特性
- 七、Redis 基础命令---任务队列
- Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based!
- Nginx、Lighttpd与Apache的区别
- uva1388(数学)
- dp小结
- coco2dx 中常用的宏定义
- android SparseArray替代HashMap的分析
- Codeforces Round #287 (Div. 2) A B C
- git设置ssh key
- C++11 中的线程、锁和条件变量
- 解剖Nginx·模块开发篇(1)跑起你的 Hello World 模块!
- 八、Redis 基础命令---管理--持久化--RDB
- 交换两个变量的值