DP课后题(2,3)

15-2回文字符串

利用LCS算法

#include<iostream>
#include<vector>
#include<algorithm>
#include<utility>
#include<string>
#include<map>
using namespace std;
typedef vector<vector<int>> vec2_int;
void fun()
{  
    string x="qcharacter";//q为缓冲字符
    string y="tretcarahc";
    //vector<char> ans;
    int m=x.length();
    int n=y.length();
    vector<int> temp(n,0);
    vec2_int b(m,temp);
    vec2_int c(m,temp);
    char x_q=x[1];
    char y_q=y[1];
    int x1_index=find(y.begin(),y.end(),x_q)-y.begin();
    int y1_index=find(x.begin(),x.end(),y_q)-x.begin();
    
    for(int j=1;j<n;j++)
    {
        for(int i=1;i<m;i++)
        {
            if(x[i]==y[j])
            {
                b[i][j]=b[i-1][j-1]+1;
                c[i][j]=1;
                
            }
            else{
                b[i][j]=max(b[i][j-1],b[i-1][j]);
                if(b[i][j-1]>b[i-1][j])c[i][j]=3;
                else c[i][j]=2;
            }


        }
    }
    map<int ,string> map_temp;
    map_temp.insert(make_pair(1,"左上"));
    map_temp.insert(make_pair(2,"上方"));
    map_temp.insert(make_pair(3,"左方"));
    string s_ans;
    for(int i=m-1;i>=0;i--)
    {
        for(int j=n-1;j>=0;j--)
        {
            if(c[i][j]==1)
            {
                s_ans.insert(s_ans.end(),x[i]);
                i--;
            }
            else{
                if(c[i][j]==2)
                {
                    i--;
                    j++;
                }
            }
            
        }
    }
    cout<<s_ans<<'\n';
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            cout<<map_temp[c[i][j]]<<'_'<<x[i]<<"_"<<b[i][j]<<"  ";
            
        }
        cout<<'\n';
    }
    
    
}
int main()
{
    fun();
    return 0;
}

15-3欧几里得

将问题改为两个人分别从第一个点走到最后一个点,点不重复。

dis[i][j]代表为一个人已经走到i点另一个人已经走到j点。为对称矩阵。
初始化dis[1][2]=dis[2][1]=dis(1,2);
不妨令i>j;
当j!=i-1时;
dis[i][j]=dis[i-1][j]+dis(i,i-1);
当j=i-1时
例如要计算dis[7][6]时,我们可以列举dis[6][5].dis[6][4]...,到目标的最小值;
最后我们要计算dis[i][i],
例如dis[7][7]=dis[7][6]+dis[6][7];
#include<iostream>
#include<vector>
#include<algorithm>
#include<utility>
#include<string>
#include<map>
#include<math.h>

using namespace std;
typedef vector<vector<int>> vec2_int;
typedef vector<vector<double>> vec2_dou;
typedef pair<int,int> point; 
typedef map<int,int>::iterator map_iter;
double distance(pair<int,int> p1,pair<int,int> p2)
{
    return pow(pow(p1.first-p2.first,2.0)+pow(p1.second-p2.second,2),0.5);
}
void fun()
{  
    vector<pair<int,int>> points={
        make_pair(-1,-1),
        make_pair(0,6),make_pair(1,0),
        make_pair(2,3),make_pair(5,4),
        make_pair(6,1),make_pair(7,5),
        make_pair(8,2)
    };
    vector<int> ac;
    int m=points.size();
    vector<double> vec_temp(m,0);
    vec2_dou ans_temp(m,vec_temp);
    ans_temp[1][2]=ans_temp[2][1]=distance(points[1],points[2]);
    for(int i=3;i<m;i++)
    {
        for(int j=1;j<i;j++)
        {
            if(j==i-1)
            {
                ans_temp[i][j]=99999;
               for(int k=1;k<j;k++)
               {
                   ans_temp[i][j]=min(ans_temp[i][j],ans_temp[j][k]+distance(points[k],points[i]));
                   ans_temp[i][j]=min(ans_temp[i][j],ans_temp[i][k]+distance(points[k],points[j]));
                  
               }
               
            }
            else
            {
                ans_temp[i][j]=ans_temp[i-1][j]+distance(points[i],points[i-1]);

            }
            cout<<ans_temp[i][j]<<'\t';
        }
        ans_temp[i][i]=ans_temp[i][i-1]+distance(points[i],points[i-1]);
        cout<<ans_temp[i][i]<<'\t';
        cout<<'\n';
    }
    for(int i:ac)
    {
        cout<<i<<'\t';
    }

    /*vector<double> dis(points.size()-1,9999999);
    auto first_po=points.begin();
    auto finnal_po=points.end();
    finnal_po--;
    auto in_point=points.begin();
    auto out_point=points.begin();
    auto cur_point=points.begin();
    dis[0]=2*distance(first_po,finnal_po);
    for(int i=1;i<points.size()-1;i++)
    {
        ++cur_point;
        double p=dis[i-1]
                -distance(in_point,finnal_po)
                +distance(in_point,cur_point)+distance(cur_point,finnal_po);
        double q=dis[i-1]
               -distance(out_point,finnal_po)
               +distance(out_point,cur_point)+distance(cur_point,finnal_po);
        dis[i]=min(p,q);
        if(p<q)
        {
            in_point=cur_point;
        }
        else{
            out_point=cur_point;
        }       
        cout<<dis[i]<<'\t'<<'\t';

    }*/
    
    
}
int main()
{
    fun();
    return 0;
}

用贪心竟然有相同结果!!!离谱!!!!!!!!!!!而且O(n)复杂度!!!!!!!

//贪心算法
#include<iostream>
#include<vector>
#include<algorithm>
#include<utility>
#include<string>
#include<map>
#include<math.h>

using namespace std;
typedef vector<vector<int>> vec2_int;
typedef pair<int,int> point; 
typedef map<int,int>::iterator map_iter;
double distance(map_iter p1,map_iter p2)
{
    return pow(pow(p1->first-p2->first,2.0)+pow(p1->second-p2->second,2),0.5);
}
void fun()
{  
    map<int,int> points={
        make_pair(0,6),make_pair(1,0),
        make_pair(2,3),make_pair(5,4),
        make_pair(6,1),make_pair(7,5),
        make_pair(8,2)
    };
    vector<double> dis(points.size()-1,9999999);
    auto first_po=points.begin();
    auto finnal_po=points.end();
    finnal_po--;
    auto in_point=points.begin();
    auto out_point=points.begin();
    auto cur_point=points.begin();
    dis[0]=2*distance(first_po,finnal_po);
    for(int i=1;i<points.size()-1;i++)
    {
        ++cur_point;
        double p=dis[i-1]
                -distance(in_point,finnal_po)
                +distance(in_point,cur_point)+distance(cur_point,finnal_po);
        double q=dis[i-1]
               -distance(out_point,finnal_po)
               +distance(out_point,cur_point)+distance(cur_point,finnal_po);
        dis[i]=min(p,q);
        if(p<q)
        {
            in_point=cur_point;
        }
        else{
            out_point=cur_point;
        }       
        cout<<dis[i]<<'\t'<<'\t';

    }
    
    
}
int main()
{
    fun();
    return 0;
}