动态规划

1.双调欧几里得旅行商问题


#include<iostream>
#include<cmath>
#include<cfloat>
using namespace std;
#define n 7
class point
{
public:
    double x,y;
    void set()
    {
        cin>>x>>y;
    }
};

double dist(point p,point q)
{
    return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}

void Euclidean_TSP(point p[n+1],double b[][n],int r[][n])
{
    b[1][2]=dist(p[1],p[2]);
    for(int j=3;j<=n;j++)
    {
        for(int i=1;i<j-1;i++)
        {
            b[i][j]=b[i][j-1]+dist(p[j-1],p[j]);
            r[i][j]=j-1;
        }
        b[j-1][j]=DBL_MAX;
        for(int k=1;k<j-1;k++)
        {
            double q=b[k][j-1]+dist(p[k],p[j]);
            if(q<b[j-1][j])
            {
                b[j-1][j]=q;
                r[j-1][j]=k;
            }
        }
    }
    b[n][n]=b[n-1][n]+dist(p[n-1],p[n]);
}

int main()
{
    point p[n+1];
    for(int i=1;i<=n;i++)p[i].set();
    double b[n][n];
    int r[n][n];
    Euclidean_TSP(p,b,r);
    cout<<b[n][n]<<endl;
}

2.字符串编辑距离

Google2013校园招聘笔试题

给定一个源串和目标串,能够对源串进行如下操作:
1.在给定位置上插入一个字符
2.替换任意字符
3.删除任意字符
要求写一个程序,返回最少的操作数,使得对源串进行这些操作后等于目标串,源串和目标串的长度都小于2000。


#include<iostream>
using namespace std;
#define m 7
#define n 5

int min(int a,int b,int c)
{
    int temp=(a<b)?a:b;
    return (temp<c)?temp:c;
}

void LD(char s[],char d[],int f[][n+1])
{
    int i,j;
    for(i=0;i<=m;i++)f[i][0]=i;
    for(j=1;j<=n;j++)f[0][j]=j;
    for(i=1;i<=m;i++)
    {
        for(j=1;j<=n;j++)f[i][j]=min(f[i][j-1]+1,f[i-1][j-1]+(s[i-1]==d[j-1]?0:1),f[i-1][j]+1);
    }
}

int main()
{
    char s[m],d[n];
    strcpy(s,"failing");
    strcpy(d,"sailn");
    int f[m+1][n+1];
    LD(s,d,f);
    cout<<f[m][n]<<endl;
    return 0;
}

3.最大连续乘积子串


#include<iostream>  
using namespace std;  

float max(float x,float y,float z)
{
    x=x>y?x:y;
    return x>z?x:z;
}

float min(float x,float y,float z)
{
    x=x<y?x:y;
    return x<z?x:z;
}

float f(float a[],int n)
{
    float M=a[0],m=a[0],value=a[0],tmp;
    for(int i=1;i<n;i++)
    {
        tmp=max(a[i],M*a[i],m*a[i]);
        m=min(a[i],M*a[i],m*a[i]);
        M=tmp;
        if(M>value)value=M;
    }
    return value;
}

int main()
{
    float a[7]={-2.5,4,0,3,0.5,8,-1};
    cout<<f(a,7)<<endl;
    return 0;
}

4.n个骰子的点数


#include<iostream>  
using namespace std;
#define n 3
int f[n][6*n];

int g(int i,int j)
{
    if(j>0)return f[i][j];
    else return 0;
}

void dice()
{
    int i,j;
    for(i=1;i<=6;++i)f[1][i]=1;
    for(i=2;i<=n;++i)
    {
        for(j=i;j<=6*i;j++)f[i][j]=g(i-1,j-1)+g(i-1,j-2)+g(i-1,j-3)+g(i-1,j-4)+g(i-1,j-5)+g(i-1,j-6);
    }
}

int main()
{
    int i=n,s=1,a=6;
    while(i)
    {
        if(i&1)s*=a;
        i>>=1;
        a*=a;
    }
    dice();
    for(i=n;i<=6*n;++i)cout<<f[n][i]<<' '<<(float)f[n][i]/s<<endl;
    return 0;
}

5.12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、31、38、39、47。在这12个工厂中选取3个原料供应厂,使得剩余工厂到最近的原料供应厂距离之和最短,问应该选哪三个厂?


#include<iostream>  
#include<cmath>
using namespace std;  
int f[13][4];

int g(int a[],int i,int j)
{
    int tmp=(i+j)/2,s=0;
    for(int k=i;k<=j;k++)
    {
        s+=abs(a[k]-a[tmp]);
    }
    return s;
}

int sum(int a[],int m,int n)
{
    int i,j,k,s;
    for(i=1;i<=m;i++)f[i][1]=g(a,1,i);
    for(j=2;j<=n;j++)
    {
        for(i=j;i<=m;i++)
        {
            s=INT_MAX;
            for(k=j-1;k<=i-1;k++)
            {
                if(f[k][j-1]+g(a,k+1,i)<s)s=f[k][j-1]+g(a,k+1,i);
            }
            f[i][j]=s;
        }
    }
    return f[m][n];
}

int main()
{
    int a[13]={0,0,4,5,10,12,18,27,30,31,38,39,47};
    cout<<sum(a,12,3)<<endl;
    return 0;
}

6.Word Break(LeetCode)


#include<iostream>
#include<string>
#include<unordered_set>
#include<vector>
using namespace std; 

bool wordbreak(string s,unordered_set<string> dict)
{
    vector<bool> f(s.size()+1,false);
    f[0]=true;
    for(int i=1;i<=s.size();++i)
    {
        for(int j=i-1;j>=0;--j)
        {
            if(f[j] && dict.find(s.substr(j,i-j))!=dict.end())
            {
                f[i]=true;
                break;
            }
        }
    }
    return f[s.size()];
}

int main()
{
    unordered_set<string> dict;
    string s;
    while(cin>>s)dict.insert(s);
    cin>>s;
    cout<<wordbreak(s,dict)<<endl;
    return 0;
}

7.Distinct Subsequences(LeetCode)


#include<iostream>
#include<string>
#include<vector>
using namespace std; 

int DS(string S,string T)
{
    vector<vector<int> > f(T.size()+1,vector<int>(S.size()+1));
    int i,j;
    for(j=0;j<=S.size();++j)f[0][j]=1;
    for(i=1;i<=T.size();++i)f[i][0]=0;
    for(i=1;i<=T.size();++i)
    {
        for(j=1;j<=S.size();++j)
        {
            f[i][j]=f[i][j-1];
            if(T[i-1]==S[j-1])f[i][j]+=f[i-1][j-1];
        }
    }
    return f[T.size()][S.size()];
}

int main()
{
    string S="rabbbit";
    string T="rabbit";
    cout<<DS(S,T)<<endl;
    return 0;
}

8.Longest Valid Parentheses

动态规划_第1张图片

#include<iostream>
#include<string>  
#include<vector>
using namespace std;    

int LVP(string s)
{
	vector<int> f(s.size(),0);
	int max=0;
	for(int i=s.size()-2;i>=0;--i)
	{
		if(s[i]=='(')
		{
			int j=i+f[i+1]+1;
			if(j<s.size()&&s[j]==')')
			{
				f[i]=f[i+1]+2;
				if(j+1<s.size())f[i]+=f[j+1];
			}
		}
		if(f[i]>max)max=f[i];
	}
	return max;
}

int main() 
{ 
	string s=")()())";
	cout<<LVP(s)<<endl;
	return 0; 
}

9.有N个节点,每两个节点相邻,每个节点只与2个节点相邻,因此,N个顶点有N-1条边。每一条边上都有权值wi,定义节点i到节点i+1的边为wi。求:不相邻的权值和最大的边的集合。


int fun(int a[],int n)
{
	int f[N];
	f[0]=a[0],f[1]=max(a[0],a[1]);
	for(int i=2;i<n;++i)
	{
		f[i]=max(f[i-1],f[i-2]+a[i]);
	}
	return f[n-1];
}
10.TSP


11.交替字符串
输入三个字符串s1、s2和s3,判断第三个字符串s3是否由前两个字符串s1和s2交错而成,且不改变s1和s2中各个字符原有的相对顺序。例如当s1 = “aabcc”,s2 = “dbbca”,s3 = “aadbbcbcac”时,则输出true;但如果s1 = “aabcc”,s2 = “dbbca”,s3=“accabdbbca”时,则输出false。


你可能感兴趣的:(动态规划)