pat1045Favorite Color Stripe (30)

56 篇文章 0 订阅

题意分析:

(1)给出一个有若干个数的偏好序列,同时给出另一个任意的数组,并且参照前面序列中元素出现的相对顺序(某些元素可以丢弃)依次从前往后选择数组中的元素组成一个新的数组,求这个数组的最大长度。

(2)由于求解的是从数组A中下标范围到i这个序列的顺序,选择数组B中下标范围到j的最长数组的长度,可以分解为:A中下标范围到i,B中下标范围到j-1与A中下标范围到i-1,B中下标范围到j这两个子问题,若求得这两个子问题的最大值,再根据A中第i个位置和B中第j个位置的值,合并之后得到原始问题的解,然后按照这个思路递归求解。使用二维数组maxLength[i][j],表示从数组A中前i个元素在数组B中前j个元素能够找到的最大序列长度。

可能坑点:

(1)使用动态规划的题一般会有点难度,按照分析(2),此题的A、B数组的下标从1开始,这样才能使递归的最后一层(动态规划中递归的最后一层)不至于数组越界。

解法一:直接使用递归加引用

#include <iostream>

using namespace std;
int like[201]={0};
int given[10001]={0};
int length[201][10001]={0};

int DP(int start,int end)
{
    int &ans=length[start][end];
    if(ans>0)return ans;
    if(start==0||end==0)return ans=0;
    int i=DP(start-1,end);
    int j=DP(start,end-1);
    int flag=(like[start]==given[end]?1:0);
    return ans=(i>j?i:j)+flag;
}
int main()
{
    int N,M,L;
    cin>>N>>M;
    int i;
    for(i=0;i<M;i++)cin>>like[i+1];
    cin>>L;
    for(i=0;i<L;i++)cin>>given[i+1];
    cout<<DP(M,L)<<endl;
    return 0;
}

解法二:借助记忆化数组

#include <iostream>

using namespace std;
int like[201]={0};
int given[10001]={0};
int length[201][10001]={0};
int getMaxLength(int row,int col)
{
    int i,j,max;
    for(i=1;i<=row;i++)
    {
        for(j=1;j<=col;j++)
        {
            max=length[i-1][j-1];
            if(length[i-1][j]>max)max=length[i-1][j];
            if(length[i][j-1]>max)max=length[i][j-1];
            if(like[i]==given[j])length[i][j]=max+1;
            else length[i][j]=max;
        }
    }
    return length[row][col];
}
int main()
{
    int N,M,L;
    cin>>N>>M;
    int i;
    for(i=0;i<M;i++)cin>>like[i+1];
    cin>>L;
    for(i=0;i<L;i++)cin>>given[i+1];
    cout<<getMaxLength(M,L)<<endl;
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值