DP【洛谷P1704】 寻找最优美做题曲线
【洛谷P1704】 寻找最优美做题曲线
题目背景
nodgd是一个喜欢写程序的同学,前不久(好像还是有点久了)洛谷OJ横空出世,nodgd同学当然第一时间来到洛谷OJ刷题。于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家……
题目描述
洛谷OJ刷题有个有趣的评测功能,就是系统自动绘制出用户的“做题曲线”。所谓做题曲线就是一条曲线,或者说是折线,是这样定义的:假设某用户在第b[i]天AC了c[i]道题,并且b[i]严格递增,那么该用户的做题曲线就是平面上点(i,c[i])依次连出的一条折线。比如你在第1天做了3道题,第3天做了4道题,第6天做了1道题,那么你在前6天的做题曲线就是从点(1,3)到点(2,4)到点(3,1)的连续折线。
nodgd同学可以预测出自己未来N天每条能够AC题目的数量,同时有一个很无趣的爱好,就是单调递增,nodgd强迫自己的做题曲线保持严格的单调递增。但是出于某些原因,nodgd在某些日子(共有K天)必须刷题,而且刷题数量一定是预计的数量(体现nodgd的神预测)。nodgd同学想知道,在这样的情况下,自己最多有多少天可以刷题,不过nodgd同学还有大量的数学竞赛题、物理竞赛题、英语竞赛题、美术竞赛题、体育竞赛题……要做,就拜托你来帮他算算了。
输入输出格式
输入格式:
第一行两个正整数,N和K,表示nodgd预测了未来N天每天做题的数量,其中K天必须刷题。
第二行K个正整数p[i],表示第p[i]天必须刷题(1<=p[i]<=N,保证每个p[i]不同)。
第三行N个正整数c[i],表示在第i天nodgd可以AC的题目数量必须是c[i]。
输出格式:一行。
如果能找到严格递增的做题曲线:一个正整数,表示nodgd最多有多少天可以刷题。
如果找不到严格递增的做题曲线:直接输出“impossible”(不加引号,全是小写字母)。
自己YY的做法A了两道题了,十分开心,不过看到了我的做法居然和这道题的作者的作法一样,不太开心。。。
这道题就是在一个序列中让你选定一些数,再在必选这些数的基础上找出LIS。
我的做法挺鬼畜的。
首先对于一个要选定的点,我们可以排除一些绝对不会选的点。条件就是在当前点前面的点的值如果大于当前点,那么因为当前点必选,所以就可以排除那个前面的点,同样的,如果当前点后面的点的值小于当前点的值,那么我们也不选。
这样,我们就可以得到一个新的数组,在这个数组里直接求一遍LIS就行了。
刚刚自己想了一下,忽然感觉这个做法是错误的,因为我感觉在新数组里选LIS并没有保证原本要选的点一定被选。
但是并不是这样的,(机房一堆大佬反驳我。。。可是我说我的做法错他们反驳说对是什么鬼啊。。。)
我们可以这么想,对于一个一定要选的点,经过我们的处理,在这个点之前是一段全部小于他的数,后面是一段全部大于他的数,那么不管我们在这前后两段怎么选,都一定不会有一个数去替代他的位置,也就是说,我们可以用反证法证不选他不是最优的就可以了。
开心。
code:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int wx=500017; inline int read(){ int sum=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();} return sum*f; } int n,m,ans[wx],len,tot; int flag[wx],a[wx],b[wx],f[wx],vis[wx]; int main(){ n=read();m=read(); for(int i=1,x;i<=m;i++)x=read(),flag[x]=1; for(int i=1;i<=n;i++)a[i]=read(); int last=0; for(int i=1;i<=n;i++){ if(a[i]>a[last])vis[i]=1; if(flag[i])last=i; } last=n+1;a[n+1]=0x3f3f3f3f; for(int i=n;i>=1;i--){ if(a[i]>a[last]&&flag[i]){ printf("impossible");return 0; } if(a[i]>a[last])vis[i]=0; if(flag[i])last=i; } for(int i=1;i<=n;i++){ if(vis[i])b[++tot]=a[i]; } ans[1]=b[1];len=1; for(int i=2;i<=tot;i++){ if(b[i]>ans[len]){ ans[++len]=b[i]; } else{ int pos=lower_bound(ans,ans+len,b[i])-ans; ans[pos]=b[i]; } } printf("%d\n",len); return 0; }
- LIS【p1704】寻找最优美做题曲线
- luogu P1704 寻找最优美做题曲线
- 【洛谷1272】重建道路(树形DP)
- 洛谷2344 奶牛抗议(DP+BIT+离散化)
- 九度OJ 1337:寻找最长合法括号序列 (DP)
- 洛谷P1063 能量项链(区间DP)(环形DP)
- 洛谷3600,大力期望DP
- 树形dp-洛谷 P3047 [USACO12FEB]附近的牛Nearby Cows
- 洛谷Luogu-2583 地铁间谍 (DP) HQG_AC的博客
- 洛谷.1782.旅行商的背包(背包DP 单调队列)
- 【BZOJ1076】【SCOI2008】奖励关&【BZOJ4318】OSU!()期望dp&【洛谷1850】换教室
- 【DP】洛谷 P1541 乌龟棋
- 洛谷 P2296 寻找道路
- 洛谷 2296_寻找道路_spfa+dfs
- 洛谷P1136 迎接仪式 DP
- Ural 1519. Formula 1 优美的插头DP
- [双语阅读]研究:妈妈曲线优美 宝宝聪明伶俐
- 尼克的任务 dp 洛谷1280
- 传纸条 NOIP2008 洛谷1006 二维dp
- 洛谷1417 烹调方案 dp 贪心