GXUOJ-算法-第二次作业

打印 上一主题 下一主题

主题 802|帖子 802|积分 2406

1.矩阵连(链)乘

题目描述

GXUOJ | 矩阵连乘

代码解答

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=50;
  4. int m[N][N];
  5. int p[N];
  6. int n;
  7. int main(){
  8.         cin>>n;
  9.        
  10.     //m[i][j] 存储的是从第 i 个矩阵到第 j 个矩阵这一段矩阵链相乘的最小计算次数。
  11.         for(int i=0;i<=n;i++){
  12.                 cin>>p[i];
  13.                 m[i][i]=0;
  14.         }
  15.        
  16.         for(int r=2;r<=n;r++){
  17.                 for(int i=1;i<=n-r+1;i++){
  18.                        
  19.                        
  20.                         int j=r+i-1;
  21.                         //初始化, m[i][j] 相当于 Ai,Ai+1···Aj 的最小乘积,       
  22.                         //m[i+1][j]是A【i+1]到A[j]的最小乘积
  23.                         m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
  24.                         //k=i+1/i  k<=j/k<j 四个结合都没有影响
  25.                         for(int k=i+1;k<j;k++){
  26.                                 int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
  27.                                 if(t<m[i][j])
  28.                                         m[i][j]=t;
  29.                         }
  30.                 }
  31.         }
  32.         cout<<m[1][n];
  33. }
复制代码
解题思绪

   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)

代码解答

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main(){
  4.         string text1,text2;
  5.         cin>>text1>>text2;
  6.         int len1=text1.length();
  7.         int len2=text2.length();
  8.         //这两个都可以
  9.         //int len1=text1.size();
  10.         //int len2=text2.size();
  11.         int dp[1000][1000]={0};
  12.        
  13.         for(int i=0;i<len1;i++){
  14.                 for(int j=0;j<len2;j++){
  15.                         if(text1[i]==text2[j])
  16.                     //当前字符相等时,最长公共子序列长度在之前的基础上加 1
  17.                                 dp[i+1][j+1]=dp[i][j]+1;
  18.                         else
  19.                                 dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
  20.                         //这意味着取text1去掉当前字符与text2的最长公共子序列长度
  21.                                 //和text2去掉当前字符与text1的最长公共子序列长度中的最大值。
  22.        }
  23.         }
  24.        
  25.         cout<<dp[len1][len2];
  26.         return 0;
  27. }
复制代码


3.0-1背包题目

题目描述

GXUOJ | 0-1背包题目

代码解答

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,m;
  4. const int N=1005;
  5. int w[N],v[N],dp[N];
  6. int main(){
  7.         cin>>n>>m;
  8.         for(int i=0;i<n;i++)
  9.                 cin>>v[i];
  10.         for(int i=0;i<n;i++)
  11.                 cin>>w[i];
  12.                
  13.         for(int i=0;i<n;i++){
  14.                 for(int j=m;j>=w[i];j--){
  15.                         // 状态转移方程:选择当前物品或不选择当前物品中的较大价值
  16.                         dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
  17.                 }
  18.         }
  19.         cout<<dp[m];
  20. }
复制代码

4.带权区间调度

题目描述

GXUOJ | 带权区间调度(Weighted Interval Scheduling)


代码解答

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=1005;
  4. struct Task{
  5.         int start,end,value;
  6. }tasks[N];
  7. int dp[N];
  8. bool compareTask(Task a,Task b){
  9.         return a.end<b.end;
  10. }
  11. int find(int i){
  12.         int l=0;int r=i-1;
  13.         while(l<=r){
  14.                 int mid=(l+r)/2;
  15.                 // 如果中间位置任务的结束时间小于等于当前任务i的开始时间
  16.         // 说明可能存在更靠后的不冲突任务,调整左边界
  17.                 if(tasks[mid].end<=tasks[i].start)
  18.                         l=mid+1;
  19.                 else
  20.                         r=mid-1;
  21.         }
  22.         return r;
  23. }
  24. int main(){
  25.         int n;cin>>n;
  26.         for(int i=0;i<n;i++)
  27.                 cin>>tasks[i].start>>tasks[i].end>>tasks[i].value;
  28.        
  29.         sort(tasks,tasks+n,compareTask);
  30.        
  31.         for(int i=0;i<n;i++){
  32.                 int x=find(i);
  33.                 dp[i+1]=max(dp[i],dp[x+1]+tasks[i].value);
  34.         }
  35.         cout<<dp[n];
  36.         return 0;
  37. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

兜兜零元

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表