NOIP Dp基本套路大全

前言:

Dp,一直是困扰许(我)许(这)多(一)多(个)Oler(蒟蒻)的问题之一。而在看似毫无章法与固定解题模式的Dp题中,却实实在在有那么一些基本套路,帮助我们在求解Dp的过程中能给我们或多或少提(多)供(骗)一些思(水)路(分)。

持续更新中。。。求大佬指正orz。


正文:


基础套路:

P.S:(以下的状态转移方程只是最基础的,不含其他优化)


(1)最长公共子序列

题意
询问你两个字符串的最长公共子序列。

状态转移方程

    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        if(s1[i]==s2[j])f[i][j]=f[i-1][j-1]+1;
        else f[i][j]=max(f[i-1][j],f[i][j-1]);

// 预处理: 无
// i: 枚举到的s1串的位置
// j: 枚举到的s2串的位置    
// 时间复杂度:N*M

例题
HDU 5495
HDU 1503


(2)最长不下降子序列

题意
询问你一个数列的最长不下降子序列
(拓展):一个数列能拆城的最少的不下降子序列个数。

状态转移方程(?)

  for(int i=1;i<=n;i++)
  {
    cin >> a[i];
    int left=1,right=ans;
    while(left<=right)
    {
      int mid=(left+right)/2;
      if(a[i]<=num[mid])
        right=mid-1;
      else
        left=mid+1;
    }
    if(left>ans)  ans++;
    num[left]=a[i];
  }
  cout<<ans<<endl;
  return 0;
}

// 二分+贪心,每次每次把同一位替换成更小的数。
// 时间复杂度:N*log(N)<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值