S - Making the Grade POJ - 3666 结论 将严格递减转化成非严格的
S - Making the Grade
这个题目要求把一个给定的序列变成递增或者递减序列的最小代价。
这个是一个dp,对于这个dp的定义我觉得不是很好想,如果第一次碰到的话。
上网看了一下题解,dp[i][j]表示前面 i 位已经是有序的了,第 i+1 位变成第j大的最小代价。
这个转移可以保证有序这个条件。
递增递减d两次。
这个题目要离散化,为什么要离散化呢,推荐博客
我以前就是感觉数据大就要离散化,不然数组存不下,不过看了这篇题解感觉他讲的很对啊。
#include <cstring>
#include <queue>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <vector>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e3 + ;
ll dp1[maxn][maxn], dp2[maxn][maxn];
int a[maxn], b[maxn]; int main()
{
int n;
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];
sort(b + , b + + n);
int len = unique(b + , b + + n) - b - ;
for (int i = ; i <= n; i++) {
for (int j = ; j <= len; j++) {
dp1[i][j] = dp2[i][j] = inf64;
}
}
for (int i = ; i <= len; i++) {
dp1[][i] = abs(b[i] - a[]);
dp2[n][i] = abs(b[i] - a[n]);
}
for(int i=;i<n;i++)
{
ll tmp = inf64;
for(int j=;j<=len;j++)
{
tmp = min(tmp, dp1[i][j]);//这一步我感觉很巧妙,优化了一个for循环,
//这里是再找j前面的最小的那个dp[i][j],因为dp[i][j]=min(dp[i-1][1~j])+abs()
dp1[i + ][j] = min(dp1[i + ][j], tmp + abs(a[i + ] - b[j]));
}
}
ll ans = inf64;
for (int i = ; i <= len; i++) ans = min(ans, dp1[n][i]);
for(int i=n;i>;i--)
{
ll tmp = inf64;
for(int j=;j<=len;j++)
{
tmp = min(tmp, dp2[i][j]);
dp2[i - ][j] = min(dp2[i - ][j], tmp + abs(a[i - ] - b[j]));
}
}
for (int i = ; i <= len; i++) ans = min(ans, dp2[][i]);
printf("%lld\n", ans);
return ;
}
然后还有一个题目和这个很类似,好像比这个要难一点,所以我才先写的这个题目。
C. Sonya and Problem Wihtout a Legend
之前的那篇博客也有推荐
这个题目我居然没有写出来,其实和上面基本上是一样的,只有一点点的区别,上面的是非严格的,这个是严格递增的。
然后我不知道怎么转化,或者说我尝试过了,发现不太对。
然后我就去搜了题解,发现有一种方法可以把严格转化成非严格就是 a[i]-i
这样之后求非严格就可以了,然后要注意因为这个是求差值最小,所以这个不会影响答案,
知道这个就很简单了,这个结论以后不要忘记
#include <cstring>
#include <queue>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <vector>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 3e3 + ;
ll dp[maxn][maxn];
ll a[maxn], b[maxn]; int main()
{
int n;
scanf("%d", &n);
for (int i = ; i <= n; i++) {
scanf("%lld", &a[i]);
a[i] -= i;
b[i] = a[i];
}
sort(b + , b + + n);
int len = unique(b + , b + + n) - b - ;
for (int i = ; i <= n; i++) {
for (int j = ; j <= len; j++) {
dp[i][j] = inf64;
}
}
for (int i = ; i <= len; i++) dp[][i] = abs(a[] - b[i]);
for(int i=;i<n;i++)
{
ll tmp = inf64;
for(int j=;j<=len;j++)
{
tmp = min(dp[i][j], tmp);
dp[i + ][j] = min(dp[i + ][j], tmp + abs(a[i + ] - b[j]));
}
}
ll ans = inf64;
for (int i = ; i <= len; i++) ans = min(ans, dp[n][i]);
printf("%lld\n", ans);
return ;
}
S - Making the Grade POJ - 3666 结论 将严格递减转化成非严格的的更多相关文章
- A-Making the Grade(POJ 3666)
Making the Grade Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4656 Accepted: 2206 ...
- Making the Grade POJ - 3666
A straight dirt road connects two fields on FJ's farm, but it changes elevation more than FJ would l ...
- DP:Making the Grade(POJ 3666)
聪明的修路方案 题目大意:就是农夫要修一条路,现在要求这条路要么就是上升的,要么就是下降的,总代价为∑|a[i]-b[i]|,求代价最低的修路方案, (0 ≤ β≤ 1,000,000,000) , ...
- 「POJ 3666」Making the Grade 题解(两种做法)
0前言 感谢yxy童鞋的dp及暴力做法! 1 算法标签 优先队列.dp动态规划+滚动数组优化 2 题目难度 提高/提高+ CF rating:2300 3 题面 「POJ 3666」Making th ...
- Poj 3666 Making the Grade (排序+dp)
题目链接: Poj 3666 Making the Grade 题目描述: 给出一组数,每个数代表当前位置的地面高度,问把路径修成非递增或者非递减,需要花费的最小代价? 解题思路: 对于修好的路径的每 ...
- 把一个序列转换成非严格递增序列的最小花费 POJ 3666
//把一个序列转换成非严格递增序列的最小花费 POJ 3666 //dp[i][j]:把第i个数转成第j小的数,最小花费 #include <iostream> #include < ...
- B - Housewife Wind POJ - 2763 树剖+边权转化成点权
B - Housewife Wind POJ - 2763 因为树剖+线段树只能解决点权问题,所以这种题目给了边权的一般要转化成点权. 知道这个以后这个题目就很简单了. 怎么转化呢,就把这个边权转化为 ...
- POJ - 3666 Making the Grade(dp+离散化)
Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more tha ...
- POJ 3666 Making the Grade(二维DP)
题目链接:http://poj.org/problem?id=3666 题目大意:给出长度为n的整数数列,每次可以将一个数加1或者减1,最少要多少次可以将其变成单调不降或者单调不增(题目BUG,只能求 ...
随机推荐
- pgsql中的行锁
pgsql中的行锁 前言 用户可见的锁 regular Lock 行级别 FOR UPDATE FOR NO KEY UPDATE FOR SHARE FOR KEY SHARE 测试下加锁之后的数据 ...
- std::string::assign函数
string& assign (const string& str); string& assign (const string& str, size_t subpos ...
- ConcurrentHashMap 同步安全 的真正含义(stringbuff 是同步安全的,stringbutter 不安全)
同步安全的集合,在多线程下用到这个map是安全的,但这个安全指的是什么?线程安全指的是指get.remove.put等操作时即同一对象,同一时间只有一个线程能在这几个方法上运行,也就是说线程安全是在这 ...
- Java JUC之Atomic系列12大类实例讲解和原理分解
Java JUC之Atomic系列12大类实例讲解和原理分解 2013-02-21 0个评论 作者:xieyuooo 收藏 我要投稿 在java6以后我们不但接触到了Loc ...
- 【漏洞通告】Linux Kernel 信息泄漏&权限提升漏洞(CVE-2020-8835)通告
0x01漏洞简介: 3月31日, 选手Manfred Paul 在Pwn2Own比赛上用于演示Linux内核权限提升的漏洞被CVE收录,漏洞编号为CVE-2020-8835.此漏洞由于bpf验证系统在 ...
- Spring Cloud和eureka启动报错 解决版本依赖关系
导读 An attempt was made to call a method that does not exist. The attempt was made from the following ...
- VulnHub靶场学习_HA: ARMOUR
HA: ARMOUR Vulnhub靶场 下载地址:https://www.vulnhub.com/entry/ha-armour,370/ 背景: Klaw从“复仇者联盟”超级秘密基地偷走了一些盔甲 ...
- 利用Ajax实现异步请求
Ajax 1.课程引入 静态网站和动态网站都是同步的,但同步方式有缺点:页面请求响应式阻塞,影响用户体验 为了解决这个问题,可以通过变通的手段实现页面的局部更新(隐藏帧),由于隐藏 ...
- PHP函数:fopen
fopen() - 打开文件或者 URL. 注意:array_key_exists() 仅仅搜索第一维的键. 多维数组里嵌套的键不会被搜索到. 说明: fopen ( string $filenam ...
- vue2.x学习笔记(四)
接着前面的内容:https://www.cnblogs.com/yanggb/p/12563162.html. 模板语法 vue使用了基于html的模板语法,允许开发者声明式地将dom绑定到底层vue ...