Zut_round 8(多维dp1)

A - 编辑距离

题目
题意:替换、插入、删除。问需要变换多少次可将字符串转换为目的串。
思路:遍历两个字符串;
相同:在a删除一个字符去匹配b、a添加一个字符去匹配b、a不变的时候去匹配b中选择一个最小的。
不同:在a删除一个字符去匹配b、a添加一个字符去匹配b、a替换一个字符去匹配b中选择一个最小的。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <math.h>
#include <cstdio>
#include <cstdlib>
#define INF 0x3f3f3f3f
using namespace std;

int m[1100][1100];
char a[1100],b[1100];
int fun(int a,int b,int c)
{
    a=min(a,b);
    return min(a,c);
}
int main()
{
    scanf("%s%s",a+1,b+1);
    int lena,lenb,i,j;
    lena=strlen(a+1);
    lenb=strlen(b+1);
    for(i=0; i<=lena; i++)
        for(j=0; j<=lenb; j++)
            m[i][j]=INF;
    for(i=0; i<=lena; i++)
        m[i][0]=i;
    for(i=0; i<=lenb; i++)
        m[0][i]=i;
    for(i=1; i<=lena; i++)
        for(j=1; j<=lenb; j++)
        {
            if(a[i]==b[j])
                m[i][j]=fun(m[i-1][j]+1,m[i][j-1]+1,m[i-1][j-1]);
            else
                m[i][j]=fun(m[i-1][j]+1,m[i][j-1]+1,m[i-1][j-1]+1);
        }
    cout<<m[lena][lenb]<<endl;
    return 0;
}

B - LCS 裸题

题目
题意:输出两个字符串的最长公共子序列。
思路:先求出dp数组,根据dp数组倒着遍历一遍将字符串找出来。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
int m[1100][1100];
int main()
{
    char a[1100],b[1100];
    stack<char> s;
    int lena,lenb,i,j;
    scanf("%s%s",a+1,b+1);
    lena=strlen(a+1);
    lenb=strlen(b+1);
    memset(m,0,sizeof(m));
    for(i=1; i<=lena; i++)
        for(j=1; j<=lenb; j++)
            if(a[i]==b[j])
                m[i][j]=m[i-1][j-1]+1;
            else
                m[i][j]=max(m[i-1][j],m[i][j-1]);
    for(i=lena,j=lenb; i>=1, j>=1;)
    {
        if(a[i]==b[j])
        {
            s.push(a[i]);
            i--;
            j--;
        }
        else if(m[i-1][j]>m[i][j-1])
            i--;
        else
            j--;
    }
    while(!s.empty())
    {
        cout<<s.top();
        s.pop();
    }
    cout<<endl;
    return 0;
}

C - 编辑距离++

题目
题意:给一个母串(循环的)。再给几个字符串(长度不超过10)。问这几个字符串需要变化多少次,可以变成母串的子串。输出这个字符串和变换次数。
思路:因为母串是循环的,且给出的字符串长度不超过10,因此可将母串延长10个字符,就可达到循环的效果。

#include <iostream>
#include <cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int dp[20][110000];
int fun(char *s,char *str,int len,int lenstr)
{
    int i,j;
    int mi=INF;
    for(i=0; i<=len; i++)
        dp[i][0]=i;
    for(i=1; i<=len; i++)
    {
        for(j=1; j<=lenstr; j++)
        {
            dp[i][j]=min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+((s[i-1]==str[j-1])?0:1));
            if(i==len)
                mi=min(mi,dp[i][j]);
        }
    }
    return mi;
}
int main()
{
    char str[110000];
    while(cin>>str)
    {
        memset(dp,0,sizeof(dp));
        char s[20][20];
        int lenstr,len;
        lenstr=strlen(str);
        int n,i,j;
        for(i=0; i<=10; i++)
            str[lenstr+i]=str[i];
        str[i]='\0';
        int re=INF,index=0;
        cin>>n;
        for(i=0; i<n; i++)
        {
            cin>>s[i];
            int mi=INF;
            len=strlen(s[i]);
            if(len>lenstr)
                for(j=0; j<lenstr; j++)
                    mi=min(mi,fun(s[i],str+j,len,lenstr));
            else
                mi=min(mi,fun(s[i],str,len,lenstr+min(10,lenstr)));
            if(mi<re||(re==mi)&&(strcmp(s[index],s[i])>0))
            {
                re=mi;
                index=i;
            }
        }
        cout<<s[index]<<' '<<re<<endl;
    }
    return 0;
}

E - A Prosperous Lot

题目
题意:0469有一个圈,8有两个圈,12357没有圈,输入k代表圈的个数,输出一个符合的数字
思路:18个8有36个圈,在不超过18位的数字中,18个8的圈数最多,因此若k>36就输出-1。#

#include <iostream>

using namespace std;

int main()
{
    int k;
    while(cin>>k)
    {
        if(k>36)
            cout<<"-1"<<endl;
        else{
            int i;
            for(i=0;i<k/2;i++)
                cout<<'8';
            if(k&1)
                cout<<'9';
            cout<<endl;
        }
    }
    return 0;
}

F - A Compatible Pair

题目
题意:给定两个数列 A、B ,元素个数分别为 n、m (2<=n,m<=50) 。数列中所有元素大小均在 -10 ^{9}到10 ^{9}之间。
现要求在 AA数列中删掉一个元素,使得 A 中任一元素和 B 中任一元素相乘的共(n−1)×m 种可能的值中的最大值最小。输出该最大值。
思路:枚举。

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
ll a[55],b[55];
int main()
{
    int n,m;
    ll a[55],b[55],c[55];
    cin>>n>>m;
    for(int i=0; i<n; ++i)
        cin>>a[i];
    for(int i=0; i<m; ++i)
        cin>>b[i];
    for(int i=0; i<n; ++i)
    {
        c[i]=a[i]*b[0];
        for(int j=1; j<m; ++j)
            c[i]=max(c[i],a[i]*b[j]);
    }
    sort(c,c+n);
    cout<<c[n-2]<<endl;
    return 0;
}


猜你喜欢

转载自blog.csdn.net/weixin_44350170/article/details/105799659