1.矩阵连(链)乘
题目描述
GXUOJ | 矩阵连乘
代码解答
- #include<bits/stdc++.h>
- using namespace std;
- const int N=50;
- int m[N][N];
- int p[N];
- int n;
- int main(){
- cin>>n;
-
- //m[i][j] 存储的是从第 i 个矩阵到第 j 个矩阵这一段矩阵链相乘的最小计算次数。
- for(int i=0;i<=n;i++){
- cin>>p[i];
- m[i][i]=0;
- }
-
- for(int r=2;r<=n;r++){
- for(int i=1;i<=n-r+1;i++){
-
-
- int j=r+i-1;
- //初始化, m[i][j] 相当于 Ai,Ai+1···Aj 的最小乘积,
- //m[i+1][j]是A【i+1]到A[j]的最小乘积
- m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
- //k=i+1/i k<=j/k<j 四个结合都没有影响
- for(int k=i+1;k<j;k++){
- int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
- if(t<m[i][j])
- m[i][j]=t;
- }
- }
- }
- cout<<m[1][n];
- }
复制代码 解题思绪
i代表开始的下标,j代表结束的下标,r代表矩阵的长度。
m[j] 存储的是从第 i 个矩阵到第 j 个矩阵这一段矩阵链相乘的最小计算次数。
当我们计算(Ai*···*Ak)和(Ak*···Aj)这两个子矩阵链乘结果相乘时,
就相当于计算两个矩阵相乘,此中第一个子矩阵链乘结果是
p[i-1]*p[k]一个的矩阵,第二个子矩阵链乘结果是p[k]*p[j]一个的矩阵。
根据矩阵乘法运算量的计算公式,这两个子矩阵链乘结果相乘所需的乘法次数就是
p[i - 1] * p[k] * p[j]。
2.最长公共子序列(LCS)
题目描述
GXUOJ | 最长公共子序列(LCS)
代码解答
- #include<bits/stdc++.h>
- using namespace std;
- int main(){
- string text1,text2;
- cin>>text1>>text2;
- int len1=text1.length();
- int len2=text2.length();
- //这两个都可以
- //int len1=text1.size();
- //int len2=text2.size();
- int dp[1000][1000]={0};
-
- for(int i=0;i<len1;i++){
- for(int j=0;j<len2;j++){
- if(text1[i]==text2[j])
- //当前字符相等时,最长公共子序列长度在之前的基础上加 1
- dp[i+1][j+1]=dp[i][j]+1;
- else
- dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
- //这意味着取text1去掉当前字符与text2的最长公共子序列长度
- //和text2去掉当前字符与text1的最长公共子序列长度中的最大值。
- }
- }
-
- cout<<dp[len1][len2];
- return 0;
- }
复制代码
3.0-1背包题目
题目描述
GXUOJ | 0-1背包题目
代码解答
- #include<bits/stdc++.h>
- using namespace std;
- int n,m;
- const int N=1005;
- int w[N],v[N],dp[N];
- int main(){
- cin>>n>>m;
- for(int i=0;i<n;i++)
- cin>>v[i];
- for(int i=0;i<n;i++)
- cin>>w[i];
-
- for(int i=0;i<n;i++){
- for(int j=m;j>=w[i];j--){
- // 状态转移方程:选择当前物品或不选择当前物品中的较大价值
- dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
- }
- }
- cout<<dp[m];
- }
复制代码
4.带权区间调度
题目描述
GXUOJ | 带权区间调度(Weighted Interval Scheduling)
代码解答
- #include<bits/stdc++.h>
- using namespace std;
- const int N=1005;
- struct Task{
- int start,end,value;
- }tasks[N];
- int dp[N];
- bool compareTask(Task a,Task b){
- return a.end<b.end;
- }
- int find(int i){
- int l=0;int r=i-1;
- while(l<=r){
- int mid=(l+r)/2;
- // 如果中间位置任务的结束时间小于等于当前任务i的开始时间
- // 说明可能存在更靠后的不冲突任务,调整左边界
- if(tasks[mid].end<=tasks[i].start)
- l=mid+1;
- else
- r=mid-1;
- }
- return r;
- }
- int main(){
- int n;cin>>n;
- for(int i=0;i<n;i++)
- cin>>tasks[i].start>>tasks[i].end>>tasks[i].value;
-
- sort(tasks,tasks+n,compareTask);
-
- for(int i=0;i<n;i++){
- int x=find(i);
- dp[i+1]=max(dp[i],dp[x+1]+tasks[i].value);
- }
- cout<<dp[n];
- return 0;
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |