题目链接:点击查看

题目大意:给出 nnn 个问题,每个问题有如下属性:

  1. tagtagtag:标签
  2. ccc:困难度
  3. sss:奖励值

初始时 ci=2ic_i=2^ici​=2i,初始时 IQ=0IQ=0IQ=0 ,假设 lastlastlast 是最后一个回答的问题,则需要满足 ∣ci−clast∣>IQ|c_i-c_{last}|>IQ∣ci​−clast​∣>IQ 才可以回答问题 iii,且回答之后会发生的变化:

  1. IQ=∣ci−clast∣IQ=|c_i-c_{last}|IQ=∣ci​−clast​∣
  2. 获得 ∣si−slast∣|s_i-s_{last}|∣si​−slast​∣ 的奖励
  3. lastlastlast 变成 iii

可以以任意顺序回答任意问题任意次,问最大可以获得的奖励值是多少

题目分析:动态规划问题,先不考虑题目限制,一开始设计的状态是 dpi,jdp_{i,j}dpi,j​ ,指倒数第二次回答的是问题 iii ,最后一次回答的是问题 jjj 的最大贡献,正确性显然,但是转移的方程好像有点爆

不过仔细观察状态之间的转移,若 dpi,jdp_{i,j}dpi,j​ 想要转移到 dpj,kdp_{j,k}dpj,k​,当且仅当 ∣ck−ci∣>∣ci−cj∣|c_k-c_i|>|c_i-c_j|∣ck​−ci​∣>∣ci​−cj​∣ 才行

将模型放到图论上去,就变成了:有 nnn 个点,任意两点之间都可以建边,且边权为 ∣ci−cj∣|c_i-c_j|∣ci​−cj​∣ 的一个无向图,那么我们可以在无向图上从小边权向大边权进行迭代,这样复杂度就下来了

简单来说就是设计 dpidp_idpi​ 为最后一个回答的问题是 iii 的最大贡献,当迭代到 (i,j)(i,j)(i,j) 这条边时, 状态 iii 可以由状态 jjj 更新,同时状态 jjj 也有可能被状态 iii 更新(因为是无向图),所以转移方程如下:设 val=∣si−sj∣val=|s_i-s_j|val=∣si​−sj​∣

  • dpi=max(dpi,dpj+val)dp_i=max(dp_i,dp_j+val)dpi​=max(dpi​,dpj​+val)
  • dpj=max(dpj,dpi+val)dp_j=max(dp_j,dp_i+val)dpj​=max(dpj​,dpi​+val)

到此为止,我们还需要解决两个问题:

  1. 边权有相同的该怎么办
  2. 如何按照边权从小到大枚举边

关于第一点比较好论述,因为所有的边权都是诸如 ∣2i−2j∣|2^i-2^j|∣2i−2j∣ 的形式,将其转换为二进制后不难发现,这个值在区间 [i,j−1][i,j-1][i,j−1] 的位置都是 111,其他位置都是 000,所以对于任意一对互不相同的 (i,j)(i,j)(i,j) 二元对来说,其权值都是互不相同的

关于第二点,因为题目内存的限制,使得我们没办法将所有的边都存下来然后排序,但是,假如我们可以将边存下来然后排序的话又能怎样?二进制递增的速度非常快,以至于当 nnn 较大的时候,数值根本存不下,手玩一下找一下规律,不难发现二元对 (i,j)(i,j)(i,j) 权值的大小(假设 i<ji<ji<j),由 jjj 主导,当 jjj 相同的时候,权值大小与 iii 呈负相关的关系

所以在按照权值大小枚举所有边的时候,可以按照:

  1. 从 2−n2 - n2−n 枚举 jjj
  2. 从 j−1j -1j−1 枚举 iii

按照上述顺序去枚举所有的二元对 (i,j)(i,j)(i,j) ,就可以满足枚举的边权是从小到大的了

代码:

// Problem: D. Genius
// Contest: Codeforces - Codeforces Round #708 (Div. 2)
// URL: https://codeforces.com/contest/1497/problem/D
// Memory Limit: 32 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=5e3+100;
LL dp[N],tag[N],s[N];
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--) {memset(dp,0,sizeof(dp));int n;read(n);for(int i=1;i<=n;i++) {read(tag[i]);}for(int i=1;i<=n;i++) {read(s[i]);}for(int j=2;j<=n;j++) {for(int i=j-1;i>=1;i--) {if(tag[i]==tag[j]) {continue;}LL dpi=dp[i],dpj=dp[j],val=abs(s[i]-s[j]);dp[i]=max(dp[i],dpj+val);dp[j]=max(dp[j],dpi+val);}}cout<<*max_element(dp,dp+n+1)<<endl;}return 0;
}

CodeForces - 1497D Genius(dp)相关推荐

  1. Codeforces 833B 题解(DP+线段树)

    题面 传送门:http://codeforces.com/problemset/problem/833/B B. The Bakery time limit per test2.5 seconds m ...

  2. CodeForces 864E Fire dp递推

    CodeForces 864E 题意:有 n 个物品着火,每个物品要花 ti 时间扑灭,且在 >= di 时间后就会坏掉,物品价值为 pi . 问最多可以救回多少价值,物品个数,及救哪些物品(要 ...

  3. Codeforces 864E - Fire(dp)

    原题连接:http://codeforces.com/problemset/problem/864/E 题意:一个人想从大火中带走一些东西.每次他只能带一个,耗时ti ,价值为pi, 当总时间超过di ...

  4. D - Yet Another Problem On a Subsequence CodeForces - 1000D (DP,组合数学)

    D - Yet Another Problem On a Subsequence CodeForces - 1000D The sequence of integers a1,a2,-,aka1,a2 ...

  5. Codeforces 480D Parcels(dp)

    题目链接:Codeforces 480D Parcels 题目大意:就是有一个用来堆放货物的板,承重力为S.现在有N件货物,每件货物有到达的时间,运走的时间,以及 重量,承重,存放盈利.如果这件货物能 ...

  6. Codeforces 711c 简单dp

    题目:http://codeforces.com/problemset/problem/711/C 题意: 有n棵树,m(1-m)种颜色,要求划分成k组,每组是连续的同一种颜色的树. 刚开始树有的已经 ...

  7. 【CodeForces】【DP】14E Camels

    CodeForces 14E Camels 题目 ◇题目传送门◆ 题目大意 给定N,TN,TN,T要求求出满足下列条件的填数方案数. 1. 对于第j(2≤j≤N−1)j(2≤j≤N−1)j(2\le ...

  8. Codeforces 1492D - Genius‘s Gambit (构造)

    Codeforces Round #704 (Div. 2) D. Genius's Gambit 题意 要求构造出两个不包含前导0的二进制数字 x , y x,y x,y,满足: x , y x,y ...

  9. Codeforces 629C 简单DP

    [题目链接] http://codeforces.com/problemset/problem/629/C [解题报告] 比赛的时候跑去做D了,这道题只是简单看了看,赛后补题把它补掉.这个题目只要想通 ...

最新文章

  1. JavaScript中实现私有属性的写类方式(2)
  2. 基于SSM实现租房平台管理系统
  3. web前端CSS2学习2017.6.22
  4. 边缘计算精华问答 | 边缘计算有哪些应用场景?
  5. Java 继承学习笔记2
  6. Unity3d大会的部分总结
  7. WinServer2008R2搭建和授权DHCP服务器详解
  8. html5片转为base64,base64和图片的互转(HTML5的File实现)
  9. jmeter.properties控制聚合报告的用户响应时间设置和smmary results
  10. tcp服务器测试网页版,tcp测试服务器
  11. 青花瓷(charles)的基本使用和注意事项
  12. 关于删除某文件需要TrustedInstaller权限的解决方法
  13. (一百五十一)Android P 真正创建sta iface的地方
  14. 外国人怎样看待Ubuntu麒麟?
  15. VTK:图形基本操作进阶——连通区域分析
  16. 系统繁忙 请稍后再试(ALI64)”
  17. 用HTML+CSS做一个简单好看的环保网页
  18. P5713_洛谷团队系统(深基3.例5)
  19. 简述相关分析(Correlation)
  20. python-猜数字游戏(0-9)

热门文章

  1. Python绘制PDF文件~超简单的小程序
  2. android11beta支持什么手机,Android 11 Beta1发布,新增多种功能,网友:Android基于 Flyme...
  3. linux 继续编译,【编译】Linux环境编译traceroute
  4. MySQL高级 - 查询缓存 - 配置参数
  5. Nginx中浏览器缓存的相关概念
  6. Nginx静态资源压缩实战内容介绍
  7. Spring反转控制
  8. 标记-整理(Mark-Compact)
  9. 利用模板模式重构JDBC操作
  10. spring相关API