首页 > 其他分享 >线性DP

线性DP

时间:2023-04-15 11:57:33浏览次数:44  
标签:return int ll namespace long 线性 DP mod

线性DP

最长公共子序列

O(n*m)写法

int a[MAXN], b[MAXM], f[MAXN][MAXM];
int dp() {
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (a[i] == b[j])
        f[i][j] = f[i - 1][j - 1] + 1;
      else
        f[i][j] = std::max(f[i - 1][j], f[i][j - 1]);
  return f[n][m];
}

O(nlogn)写法

可以转化为最长上升子序列(LIS)来求,时间复杂度可以优化到nlogn。

#include<bits/stdc++.h>
using namespace std;
int n,i,x,y,j,m,k,f[100005],c[100005],g[100005];
int main()
{
	cin>>n;
	for (i=1;i<=n;i++)
	{
		cin>>x;
		c[x]=i;
	}
	for (i=1;i<=n;i++)
	{
		cin>>y;
		f[i]=c[y];
	}
	memset(g,127,sizeof(g));
	g[0]=0;
	for (i=1;i<=n;i++)
	{
		k=lower_bound(g,g+m+1,f[i])-g-1;
		if (k==m)
			m++;
		g[k+1]=min(g[k+1],f[i]);
	}
	cout<<m<<endl;
}

最长不下降子序列

O(n2)写法

设f[i]表示以i为结尾最长的长度。

int a[MAXN], d[MAXN];
int dp() {
  d[1] = 1;
  int ans = 1;
  for (int i = 2; i <= n; i++) {
    d[i] = 1;
    for (int j = 1; j < i; j++)
      if (a[j] <= a[i]) {
        d[i] = max(d[i], d[j] + 1);
        ans = max(ans, d[i]);
      }
  }
  return ans;
}

O(nlogn)写法

memset(g,127,sizeof(g));
g[0]=0;
for (i=1;i<=n;i++)
{
	k=lower_bound(g,g+m+1,f[i])-g-1;
	if (k==m)
		m++;
	g[k+1]=min(g[k+1],f[i]);
}
cout<<m<<endl;

字符串间的编辑距离

洛谷2758

#include<bits/stdc++.h>
using namespace std;
string a, b; int lena, lenb, i, j, f[2005][2005];
int main()
{
	cin >> a >> b;
	lena = a.length();
	lenb = b.length();
	a = '.' + a; b = '.' + b;
	for (i = 1; i <= lena; i++)
		f[i][0] = i;
	for (i = 1; i <= lenb; i++)
		f[0][i] = i;
	for (i = 1; i <= lena; i++)
		for (j = 1; j <= lenb; j++)
			if (a[i] == b[j])
				f[i][j] = f[i - 1][j - 1];
			else
				f[i][j] = min({f[i - 1][j], f[i - 1][j - 1], f[i][j - 1]}) + 1;
	cout << f[lena][lenb] << '\n';
}

例题

括号序列

括号序列 - 蓝桥云课 (lanqiao.cn)

第十二届蓝桥杯软件类C/C++大学B组省赛

#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
using namespace std;
char s[5005]; long long n, u, v, i, f[5005][5005];
const int mod = 1e9 + 7;
int dp()
{
	memset(f, 0, sizeof(f));
	f[0][0] = 1;
	for (int i = 1; i <= n; i++)
	{
		if (s[i] == '(')
		{
			for (int j = 1; j <= n; j++)
				f[i][j] = f[i - 1][j - 1];
		}
		else
		{
			f[i][0] = (f[i - 1][0] + f[i - 1][1]) % mod;
			for (int j = 1; j <= n; j++)
				f[i][j] = (f[i - 1][j + 1] + f[i][j - 1]) % mod;
		}
	}
	for (int i = 0; i <= n; i++)
		if (f[n][i])
			return f[n][i];
	return -1;
}
int main()
{
	scanf("%s", s + 1);
	n = strlen(s + 1);
	u = dp();
	reverse(s + 1, s + n + 1);
	for (i = 1; i <= n; i++)
	{
		if (s[i] == '(')
			s[i] = ')';
		else s[i] = '(';
	}
	v = dp();
	cout << (u * v) % mod << '\n';
}

Research Rover

Problem - 722E - Codeforces

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, m, k, i, j, f[2005][25], b[200005], c[200005], d[200005], s, p, l, q;
const int mod = 1e9 + 7;
struct ff {
	int x, y;
}a[2005];
ll poww(ll x, ll y)
{
	if (x == 0)
		return 1;
	ll k = poww(x / 2, y) % mod;
	if (x % 2 == 1)
		return (k * k % mod) * y % mod;
	else return k * k % mod;
}
ll C(ll m, ll n)
{
	return (((c[n] * d[n - m]) % mod) * b[m]) % mod;
}
bool cmp(ff t, ff w)
{
	if ((t.x < w.x) or (t.x == w.x) and (t.y < w.y))
		return 1;
	return 0;
}
int main()
{
	cin >> n >> m >> k >> p;
	for (i = 1; i <= k; i++)
		cin >> a[i].x >> a[i].y;
	b[0] = 1; c[0] = 1; d[0] = 1;
	for (i = 1; i <= 200000; i++)
		b[i] = (poww(mod - 2, i) * b[i - 1]) % mod;
	for (i = 1; i <= 200000; i++)
	{
		c[i] = c[i - 1] * i % mod;
		d[i] = poww(mod - 2, c[i]) % mod;
	}
	sort(a,  a + k + 1, cmp);
	if ((a[k].x != n) or (a[k].y != m))
	{
		k++; a[k].x = n; a[k].y = m;
	}
	else p = p - p / 2;
	if ((a[1].x == 1) and (a[1].y == 1))
	{
		for (i = 1; i < k; i++)
		{
			a[i].x = a[i + 1].x;
			a[i].y = a[i + 1].y;
		}
		k--;
		p = p - p / 2;
	}
	for (i = 1; i <= k; i++)
	{
		f[i][0] = C(a[i].x - 1, a[i].x - 1 + a[i].y - 1);
		for (j = 1; j < i; j++)
			if (a[j].y <= a[i].y)
				for (l = 1; l <=20; l++)
				{
					f[i][l] = (f[i][l] + (f[j][l - 1] * C(a[i].x - a[j].x, a[i].x - a[j].x + a[i].y - a[j].y)) % mod) % mod;
					f[i][l] = (f[i][l] - (f[j][l] * C(a[i].x - a[j].x, a[i].x - a[j].x + a[i].y - a[j].y)) % mod) % mod;
					if (f[i][l] < 0)f[i][l] += mod;
				}
	}
	for (l = 0; l <= 20; l++)
	{
		q = (q + f[k][l] * p % mod) % mod;
		q = (q - f[k][l + 1] * p % mod) % mod;
		if (q < 0) q += mod;
		p = p - p / 2;
	}
	s = poww(mod - 2, f[k][0]) * q % mod;
	cout << s << '\n';
}

标签:return,int,ll,namespace,long,线性,DP,mod
From: https://www.cnblogs.com/ShadowAA/p/17320798.html

相关文章

  • 背包DP
    背包DP二进制分组优化考虑优化。我们仍考虑把多重背包转化成0-1背包模型来求解。预处理物品数量是2的次方。且要覆盖物品数量的点。即2n次方+1到kindex=0;for(inti=1;i<=m;i++){intc=1,p,h,k;cin>>p>>h>>k;while(k>c){k-=c;......
  • PyQt5 软件在 macOS HiDPI 模式下出现字体模糊的问题
    ​ Retina屏幕是苹果公司在2010年在 WWDC上发布的一种高密度像素的屏幕。HiDPI是一种渲染技术,它可以让Retina屏幕上的图像更加清晰。HiDPI技术会将图像渲染成两倍于原始分辨率的大小,然后再将其缩小到原始分辨率的大小,这样就可以让图像更加清晰。PyQt5编写的软件在Wi......
  • 用R语言用Nelson Siegel和线性插值模型对债券价格和收益率建模|附代码数据
    原文链接:http://tecdat.cn/?p=11758最近我们被客户要求撰写关于NelsonSiegel和线性插值模型的研究报告,包括一些图形和统计输出。保证金购买是指投资者先从银行或经纪人处借得资金购买证券,而所购买的证券作为借入资金的抵押债券基础 零息债券是指以贴现方式发行,不附息票,而于......
  • 计算机网络 传输层协议TCP和UDP
    目录一、传输层协议二、tcp协议介绍三、tcp报文格式四、tcp三次握手五、tcp四次挥手六、udp协议介绍七、常见协议和端口八、有限状态机  一、传输层协议传输层协议主要是TCP和UDP协议主要作用1.分段和重组2.会话多路复用 二、tcp协议......
  • 神策数据入选 IDC 中国客户数据平台 CDP 市场规模及厂商份额报告
    近日,IDC首发中国客户数据平台CDP市场规模及厂商份额报告,明确了CDP产品的功能和使用方式,以便减少购买者的困惑。IDC市场份额报告调研的厂商包括神策数据在内的15家企业,报告显示,市场前5家公司营业额几乎占整个市场的二分之一(47.1%)。报告中,IDC将CDP产品的主要功能分为......
  • 带有PV面板和电池的孤岛微电网的混合整数线性规划(MILP)调度
    带有PV面板和电池的孤岛微电网的混合整数线性规划(MILP)调度测试环境:MATLAB,YALMIP,GUROBI将负荷和太阳辐射预测作为输入。返回计划范围内(例如一周)的每个组件的计划。试图最大程度地减少甩负荷和减少发电量。ID:14100644860196918......
  • 解决 dpkg 安装出错后的 Sub-process /usr/bin/dpkg returned an error code (1) 错误
    在使用dpkg-i安装.deb软件包的过程中,会出现安装失败的可能。之后无论用sudoaptinstall-forsudaptautoremove等常见的修复命令都是无效的。网络上很多解决方案都直接给出需要运行的命令,不分析原因也不说明理由。我从来不尝试这样的解决方案,除非我自己知道或是只能死马......
  • 【DP】【分治】LeetCode 53. 最大子数组和
    题目链接[https://leetcode.cn/problems/maximum-subarray/description/](53.最大子数组和"https://leetcode.cn/problems/maximum-subarray/description/")思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律在数......
  • Codeforces Round #286 (Div. 2) C题 Mr. Kitayuta, the Treasure Hunter (DFS+记忆化D
    题目地址:http://codeforces.com/contest/505/problem/C从d点开始,每个点都有三个方向,形成了一棵树,那么就从跟结点开始进行dfs查找,dp数组记录当前的点和长度,当这两个条件相同的时候,显然,后面的子树是完全相同的,于是用记忆化来优化。代码如下:#include<iostream>#include<string.h>#......
  • HDU 2089 不要62 (数位DP)
    简单的数位DP。代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib.h>#include<map>#include<set>#include<stdio.h>usingnamespacestd;#d......