Alice’s Stamps(HDU - 6249)

感受
变 菜 了 , 居 然 没 有 想 出 来 变菜了,居然没有想出来
思路
n 3 暴 力 D p 应 该 很 容 易 想 的 , 这 里 不 再 赘 述 n^3暴力Dp应该很容易想的,这里不再赘述 n3Dp
设 f [ i ] [ j ] 为 前 i 张 邮 票 使 用 不 超 过 j 个 集 合 获 得 的 最 大 种 类 数 设f[i][j]为前i张邮票使用不超过j个集合获得的最大种类数 f[i][j]i使j
状 态 转 移 分 析 : 状态转移分析:
f [ i ] [ j ] 如 何 由 f [ 1.. i − 1 ] [ ] 更 新 呢 ? f[i][j]如何由f[1..i-1][]更新呢? f[i][j]f[1..i1][]
两 者 差 距 在 于 现 在 多 了 第 i 种 邮 票 ! 两者差距在于现在多了第i种邮票! i
( 1 ) 如 果 当 前 不 使 用 任 何 集 合 (1)如果当前不使用任何集合 1使
f [ i ] [ j ] = f [ i − 1 ] [ j ] f[i][j] = f[i-1][j] f[i][j]=f[i1][j]
即 不 管 现 在 有 没 有 第 i 种 邮 票 , 我 都 不 选 它 , 所 以 两 者 结 果 相 同 即不管现在有没有第i种邮票,我都不选它,所以两者结果\\相同 i
( 2 ) 如 果 当 前 使 用 一 个 集 合 , 即 作 S (2)如果当前使用一个集合,即作S 2使S
a . 如 果 S 的 左 端 点 大 于 i , 对 f [ i ] [ j ] 结 果 肯 定 无 影 响 a.如果S的左端点大于i,对f[i][j]结果肯定无影响 a.Sif[i][j]
因 为 , 此 时 大 于 i 的 邮 票 还 没 出 现 因为,此时大于i的邮票还没出现 i
b . 如 果 S 的 右 端 点 小 与 i , 此 更 新 答 案 必 < = f [ i − 1 ] [ j ] b.如果S的右端点小与i,此更新答案必<=f[i-1][j] b.Si<=f[i1][j]
为 什 么 呢 ? 因 为 现 在 的 选 择 并 没 有 涉 及 到 第 i 种 邮 票 , 所 以 用 f [ i − 1 ] [ j ] 答 案 更 优 为什么呢?因为现在的选择并没有涉及到第i种邮票,所以\\用f[i-1][j]答案更优 if[i1][j]
c . 除 了 a 与 b 情 况 , 那 么 S 的 左 端 点 < = i , S 的 右 端 点 > = i c.除了a与b情况,那么S的左端点<=i,S的右端点>=i c.abS<=iS>=i
也 就 是 从 众 多 包 括 i 的 集 合 中 选 择 一 个 最 优 的 , 其 实 看 下 图 即 可 知 道 最 优 的 是 左 端 点 距 离 i 最 远 且 与 i 有 交 集 的 也就是从众多包括i的集合中选择一个最优的,其实看下图\\即可知道最优的是左端点距离i最远且与i有交集的 iii
在这里插入图片描述
对 于 此 情 况 , 用 d p [ m i n l − 1 ] [ j − 1 ] + i − m i n l + 1 更 新 即 可 对于此情况,用dp[minl - 1][j-1]+i-minl+1更新即可 dp[minl1][j1]+iminl+1
证 毕 ! 是 不 是 很 简 单 , 我 居 然 想 了 那 么 久 ! 证毕!是不是很简单,我居然想了那么久!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e3 + 10;
int f[maxn][maxn];
int lef[maxn], l, r;
int n, m, k;
int main(){
	int t, kase = 0;
	scanf("%d", &t);
	while(t--){
		scanf("%d%d%d", &n, &m, &k);
		for(int i = 1; i <= n; i++) lef[i] = n + 1;
		for(int i = 1; i <= m; i++){
			scanf("%d%d", &l, &r);
			for(int j = l; j <= r; j++){
				lef[j] = min(lef[j], l);
			}
		}
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= m; j++){
				f[i][j] = f[i - 1][j];
				if(lef[i] <= i){
					f[i][j] = max(f[i][j], f[lef[i] - 1][j - 1] + i - lef[i] + 1);
				}
			}
		}
		printf("Case #%d: %d\n", ++kase, f[n][k]);
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值