dp可以用来解决有限集合的最值问题(max,min,count…)
dp问题分为两个部分
初始化和边界符合定义就可以
- 两个子序列的最大点积(190周赛)
 dp[i][j]的含义是到nums1[i]和nums2[j]为止的子序列的最大点积。
 1.选择nums1[i]和nums2[j]
- 不选择前面的 dp[i][j]=nums1[i] × nums2[j]
- 也选择前面的 dp[i][j]=max(dp[i][j],nums1[i]×nums2[j]+dp[i-1][j-1])
 因为dp[i][j]是截止到nums1[i]和nums2[j]中的最大点积,所以只需要dp[i-1][j-1]就可以了
 事实上从这里可以看出想法一就是想法二的情况之一
 2.选择nums1[i],不选择nums2[j]
 这种情况很容易想到就用dp[i][j-1]来表示,但实际上dp[i][j-1]并不只表示这种情况,因为dp[i][j-1]表示的是到i和j-1为止的最大点击,nums[i]不一定就选,但是这个并不影响最终结果,因为我们是求最大值,当这个状态表示的集合多的时候,不会漏掉最大值的。
 dp[i][j]=max(dp[i][j],dp[i][j-1])
 3.不选择nums1[i],选择nums2[j]
等价于dp[i-1][j]
dp[i][j]=max(dp[i][j],dp[i-1][j])
4.nums1[i],nums2[i]都不选。
这种情况包括在第二三种情况了
这样会保证两个序列长度相等吗?
会的,因为每次我们选取的操作–nums1[i]×nums2[j]+dp[i-1][j-1],都是同时选取每一个序列的一个元素.

时间复杂度O(mn)
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | class Solution {public:
 int maxDotProduct(vector<int>& nums1, vector<int>& nums2) {
 int n=nums1.size();
 int m=nums2.size();
 vector<vector<int>>dp(n+1,vector<int>(m+1,-0x3f3f3f));
 for(int i=1;i<n+1;i++)
 for(int j=1;j<m+1;j++){
 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
 dp[i][j]=max(dp[i-1][j-1]+nums1[i-1]*nums2[j-1],dp[i][j]);
 dp[i][j]=max(nums1[i-1]*nums2[j-1],dp[i][j]);
 }
 return dp[n][m];
 }
 };
 
 | 
- 最长公共子序列
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | class Solution {public:
 int longestCommonSubsequence(string text1, string text2) {
 int p = text1.size();
 int q = text2.size();
 vector<vector<int>> dp(p+1,vector<int>(q+1,0));
 for(int i=1;i<p+1;i++)
 for(int j = 1;j<q+1;j++)
 {
 if(text1[i-1]==text2[j-1])
 dp[i][j]=dp[i-1][j-1]+1;
 else
 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
 }
 return dp[p][q];
 }
 };
 
 | 
这道题到不算dp,也是用dp的一点思想来递归。
在第一层可以摆出6个ABA类型的和6个ABC类型的涂法。对于下面每一层,每一个ABA涂法可以拼接2个ABC涂法和3个ABA涂法,每一个ABC涂法可以拼接2个ABC涂法和2个ABA涂法。这样迭代可以算出第N层有几种ABA涂法和ABC涂法,相加就是答案。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | class Solution {public:
 int numOfWays(int n) {
 long long aba = 6, abc = 6;
 const int m = pow(10,9) + 7;
 for(int i=1;i<n;i++){
 int ABA,ABC;
 ABA=(abc*2+aba*3)%m;
 ABC=(abc*2+aba*2)%m;
 abc=ABC,aba=ABA;
 }
 return (abc+aba)%m;
 }
 };
 
 |