您的位置:首页 > 财经 > 产业 > 外贸公司网站怎么设计更好_手机app开发要多少钱_百度搜索引擎优化案例_互联网营销专家

外贸公司网站怎么设计更好_手机app开发要多少钱_百度搜索引擎优化案例_互联网营销专家

2024/12/23 6:04:52 来源:https://blog.csdn.net/qq_73704268/article/details/143897223  浏览:    关键词:外贸公司网站怎么设计更好_手机app开发要多少钱_百度搜索引擎优化案例_互联网营销专家
外贸公司网站怎么设计更好_手机app开发要多少钱_百度搜索引擎优化案例_互联网营销专家

线性DP

数字三角形【898】

 

(参考AcWing 898. 【算法基础课】数字三角形(线性DP) - AcWing)

#include<bits/stdc++.h>
using namespace std;
const int N=509;
int x[N][N], dp[N][N];  // x存储输入的三角形数,dp[i][j]表示从根节点到i,j结点的长度
int n;  // 三角形的层数int main() {cin >> n;  // 输入三角形的值for (int i = 1; i <= n; i++) {for (int j = 1; j <= i; j++) {cin >> x[i][j];}}// 初始化dp数组memset(dp, -0x3f3f3f3f, sizeof dp);  // 将dp数组的每个元素都设置为一个很小的值dp[1][1] = x[1][1];  // 初始化起点// 动态规划计算最大路径和for (int i = 2; i <= n; i++) {for (int j = 1; j <= i; j++) {dp[i][j] = max(dp[i-1][j-1] + x[i][j], dp[i-1][j] + x[i][j]);}}// 找到最后一行(第n行)的最大值dp[n][i]int result = -0x3f3f3f3f;for (int i = 1; i <= n; i++) {result = max(result, dp[n][i]);}cout << result;  return 0;
}

最长上升子序列【895】

(题解参考AcWing 898. 数字三角形 - AcWing)

#include<bits/stdc++.h>
using namespace std;const int N = 1010;  
int dp[N];  // dp[i] 表示以第i个元素结尾的最长递增子序列的长度
int x[N];  // x[i] 存储输入的数列
int n;  int main() {cin >> n;  for(int i = 1; i <= n; i++) cin >> x[i];  for(int i = 1; i <= n; i++) {dp[i] = 1;  // 初始化dp[i]为1,表示每个元素单独一项至少有一个递增子序列(即它自己)// 遍历前面的元素,查找是否可以扩展递增子序列for(int j = 1; j < i; j++) {// 如果x[j]小于x[i],说明可以在x[j]后面接上x[i]if(x[j] < x[i]) dp[i] = max(dp[i], dp[j] + 1);  // 更新dp[i],取最大值,表示以x[i]结尾的最大递增子序列长度}}// 计算整个数列中的最长递增子序列的长度int res = 0;  for(int i = 1; i <= n; i++) res = max(res, dp[i]);  cout << res; return 0; 
}

最长公共子序列【897】

集合表示:f[i][j]:A前i个字符,B前j个字符的公共子序列 的集合  属性:maxlen 

集合划分:
情况1:a[i],b[j] 均存在于 最长公共子序列中 (前提a[i]==b[j])
情况2:a[i] 在,b[j] 不在   (无前提)
情况3:a[i],b[j] 均不在     (无前提)
情况4:a[i]不在,b[j]在     (无前提)

需要 求得的是 max(情况1,情况2,情况3,情况4)
而:f[i-1][j-1]+1 可以表示情况1   --> a
    f[i][j-1]=max(情况2,情况3)    --> b
    f[i-1][j]=max(情况3,情况4)    --> c
所以我们最终只需要 求 max(a,b,c) 即可

#include<bits/stdc++.h>
using namespace std;const int S = 1010;  // 定义最大字符串长度
int n, m;  
int dp[S][S];  // dp数组,dp[i][j]表示s1前i个字符和s2前j个字符的最长公共子序列长度
char s1[S], s2[S];  // 存储两个字符串int main()
{cin >> n >> m;  // 输入第一个字符串for (int i = 1; i <= n; i++) cin >> s1[i];// 输入第二个字符串for (int i = 1; i <= m; i++) cin >> s2[i];// 动态规划计算最长公共子序列for (int i = 1; i <= n; i++)  // 遍历第一个字符串的每一个字符{for (int j = 1; j <= m; j++)  // 遍历第二个字符串的每一个字符{// 如果s1[i] == s2[j],则说明这两个字符可以匹配,最长公共子序列长度加1if (s1[i] == s2[j]) dp[i][j] = dp[i - 1][j - 1] + 1;else{// 如果s1[i] != s2[j],则选择去掉s1的一个字符或去掉s2的一个字符// 最大的公共子序列长度来自于去掉一个字符的情况,这里求maxdp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}}cout << dp[n][m];return 0;
}

最短编辑距离【902】

 

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
char a[N],b[N];
int n,m;
int dp[N][N];
int main()
{cin>>n;for(int i=1;i<=n;i++) cin>>a[i];cin>>m;for(int i=1;i<=m;i++) cin>>b[i];for(int i=0;i<=n;i++) dp[i][0]=i;for(int j=0;j<=m;j++) dp[0][j]=j;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1);if(a[i]==b[j])  dp[i][j]=min(dp[i][j],dp[i-1][j-1]);else dp[i][j]=min(dp[i][j],dp[i-1][j-1]+1);}}cout<<dp[n][m];return 0;
}

区间DP

石子合并【282】

#include<bits/stdc++.h>
using namespace std;const int N = 310;
// dp[i][j]表示将区间[i, j]的数合并为一堆的最小代价
int dp[N][N];
// s数组用于存储前缀和,s[i]表示前i个数的和
int s[N];
int n;
int main()
{cin >> n;// 计算前缀和for (int i = 1; i <= n; i++){cin >> s[i];s[i] += s[i - 1];}// 枚举区间长度len,从2开始,长度为1时不需要合并,代价为0for (int len = 2; len <= n; len++){// 枚举区间的左端点j,保证区间[j, j + len - 1]不超出范围for (int j = 1; j + len - 1 <= n; j++){// 确定区间的左右端点int l = j;int r = j + len - 1;// 初始化dp[l][r]为一个较大的值,方便后续取最小值操作dp[l][r] = 1e9;// 遍历区间[l, r]的分隔点k,尝试不同的合并方式for (int k = l; k <= r - 1; k++){// 更新dp[l][r]的值,取当前值和通过分隔点k合并的代价的最小值// dp[l][k]表示将区间[l, k]合并为一堆的最小代价// dp[k + 1][r]表示将区间[k + 1, r]合并为一堆的最小代价// s[r] - s[l - 1]表示将两堆合并时需要额外加上的代价,即当前区间内所有数的和dp[l][r] = min(dp[l][k] + dp[k + 1][r] + s[r] - s[l - 1], dp[l][r]);}}}// 整个区间[1, n]合并为一堆的最小代价cout << dp[1][n];return 0;
}

 所有的区间dp问题枚举时,第一维通常是枚举区间长度,并且一般 len = 1 时用来初始化,枚举从 len = 2 开始;第二维枚举起点 i (右端点 j 自动获得,j = i + len - 1)模板代码如下:

for (int len = 1; len <= n; len++) {         // 区间长度for (int i = 1; i + len - 1 <= n; i++) { // 枚举起点int j = i + len - 1;                 // 区间终点if (len == 1) {dp[i][j] = 初始值continue;}for (int k = i; k < j; k++) {        // 枚举分割点,构造状态转移方程dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + w[i][j]);}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com