NOIP前 基础动态规划模板

/*
	created by scarlyw
	基础动态规划模板 
*/
#include <bits/stdc++.h>

//0/1背包 
namespace bag_0_1 {

//O(n * m) ans为最大可行价值 
const int MAXN = 2000;
int n, m, ans;
int w[MAXN], c[MAXN], f[MAXN];
inline void solve() {
	std::cin >> m >> n;
	for (int i = 1; i <= n; ++i) std::cin >> w[i] >> c[i]; 
	for (int i = 1; i <= n; ++i)
		for (int j = m; j >= w[i]; --j)
			f[j] = std::max(f[j], f[j - w[i]] + c[i]);
	for (int i = 1; i <= m; ++i) ans = std::max(ans, f[i]);
	std::cout << ans;
}
}

//完全背包 
namespace bag_tot {

// O(n * m) ans为最大可行价值	
const int MAXN = 2000;
int n, m, ans;
int w[MAXN], c[MAXN], f[MAXN];
inline void solve() {
	std::cin >> m >> n;
	for (int i = 1; i <= n; ++i) std::cin >> w[i] >> c[i]; 
	for (int i = 1; i <= n; ++i)
		for (int j = w[i]; j <= m; ++j)
			f[j] = std::max(f[j], f[j - w[i]] + c[i]);
	for (int i = 1; i <= m; ++i) ans = std::max(ans, f[i]);
	std::cout << ans;
}
}

//最长公共子序列 
namespace longest_common_subsequence {

//O(n ^ 2)最长公共子序列,f[i][j]表示匹配到s[i], t[j]的lcs 
const int MAXN = 2000;
int f[MAXN][MAXN];
char s[MAXN], t[MAXN];
inline void lcs() {
	std::cin >> s + 1 >> t + 1;
	int lens = strlen(s + 1), lent = strlen(t + 1);
	for (int i = 1; i <= lens; ++i)
		for (int j = 1; j <= lent; ++j)
			f[i][j] = std::max(std::max(f[i - 1][j], f[i][j - 1]), 
				f[i - 1][j - 1] + (s[i] == t[j]));
	std::cout << f[lens][lent];
}
}

//最长上升序列 
namespace longest_increasing_subsequence {

//树状数组求最长上升序列O(nlogn) 
const int MAXN = 100000 + 10;
const int MAXX = 10000 + 10;

struct binary_indexed_tree {
	int bit[MAXX + 10];
	
	inline int lowbit(int i) {
		return i & -i;
	}
	
	inline void add(int i, int x) {
		for (; i <= MAXX; i += lowbit(i)) bit[i] = std::max(bit[i], x);
	}
	
	inline int query(int i) {
		int ans = 0;
		for (; i; i -= lowbit(i)) ans = std::max(ans, bit[i]);
		return ans;
	}
	
	//solve返回长度 
	inline int solve() {
		int n, x, t;
		std::cin >> n;
		for (int i = 1; i <= n; ++i)
			std::cin >> x, add(x + 1, query(x) + 1);
		return query(MAXX);
	}
} bit;

//二分求最长上升序列O(nlogn) 
int n, x, len, pos;
int lis[MAXN];

inline int find(int x) {
	int l = 0, r = len + 1;
	while (l + 1 < r) {
		int mid = l + r >> 1;
		if (lis[mid] < x) l = mid;
		else r = mid;
	}
	return l + 1;
}

//输出为序列长度 
inline void solve() {
	std::cin >> n, memset(lis, 127, sizeof(lis));
	for (int i = 1; i <= n; ++i) {
		std::cin >> x, pos = find(x);
		if (lis[pos] > x) lis[pos] = x, len = std::max(len, pos);
	}
	std::cout << len;
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值