NOIP模拟赛 baoj2933数据
来源:互联网 发布:led控制软件下载 编辑:程序博客网 时间:2024/06/10 02:44
题解:
dp很容易看出来,状态转移方程也很容易写
dp[i]=dp[j]+abs(a[j+1]-(i-j-1)) ,然后你就可以发现时间复杂度爆掉了
然后我就发现我不知道该如何优化了,于是写了暴力
然后。。。。并没有拿到说好的60分,而是25分。。。。最后发现在这区区25行的代码中,我的for是从i=2开始的
60分code:
#include<cstdio>#include<cstring>#include<algorithm>const int MAXN=100005;int n,a[MAXN],dp[MAXN];int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); memset(dp,0x3f,sizeof dp); dp[0]=0; for(int i=1;i<=n;i++) for(int j=0;j<i;j++) dp[i]=std::min(dp[i],dp[j]+abs(a[j+1]-(i-j-1))); printf("%d\n",dp[n]);}这么短我也能写错。。。
正解:
dp[i]=min(dp[j]+abs(a[j+1]-(i-j-1)))
那么令num[i]=a[i+1]+i+1;
dp[i]=min(dp[j]+abs(num[j]-i));
让我们暂且忽略这个讨厌的abs
dp[i]=min(dp[j]+num[j])-i;
现在,让我们以dp[j]+num[j]为关键字
按照从小到大的关键字搞一个优先队列
那么现在就很有意思了
虽然优先队列搞出来了,但是请注意,abs被忽略掉了
所以现在我们需要把abs的影响也算上
if(num[j]<i) minv=Q.top().key-2*num[j]+i
这样,就可以完美解决abs的问题了
注意,这时的minv仍可能不是最优的
还需要再在num[j]>i的第一个决策点和minv取min
可能细心的人会发现,如果j,k满足num[j]>i&&num[k]<i&&dp[k]+num[k]>dp[j]+num[j]
j为堆顶,但是因为num[j]>i的缘故,k一直在堆的某一个地方,被j堵住,如果此时k这个
决策点比j更优,那岂不是会错?可以证明,如果真的出现上述情况,k并不会比j点更优
有兴趣的可以去翻翻大佬的博客:JK_spc或itselaineZ(证明就是这俩家伙搞出来的)
因为证明有点复杂,不再赘述
代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<algorithm>#include<queue>const int MAXN=100005;using namespace std;int minv,n,dp[MAXN],a[MAXN];struct node{ int a,b; node(){} node(int t1,int t2){ a=t1; b=t2; } bool operator<(const node &x)const{ return a>x.a; }};priority_queue<node> Q;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i-1]); a[i-1]+=i; } Q.push(node(a[0],a[0])); minv=0x3f3f3f3f;//minv不能放在里面,minv的最小值是可能被重复使用的 for(int i=1;i<=n;i++) { dp[i]=0x3f3f3f3f; while(!Q.empty()&&Q.top().b<i) minv=min(minv,Q.top().a-2*Q.top().b),Q.pop(); dp[i]=min(dp[i],minv+i); if(!Q.empty()) dp[i]=min(dp[i],Q.top().a-i); Q.push(node(dp[i]+a[i],a[i])); } printf("%d",dp[n]);}
- NOIP模拟赛 baoj2933数据
- 【重庆市NOIP模拟赛】数据
- NOIP模拟赛题目以及数据
- noip模拟赛 双城记
- 【noip模拟赛】密码
- 10.10NOIP模拟赛
- 10.08NOIP模拟赛
- 10.11NOIP模拟赛
- 10.12NOIP模拟赛
- 10.13NOIP模拟赛
- 【NOIP模拟赛】小奇挖矿
- NOIP模拟赛--军训
- 【NOIP模拟赛】数列
- noip模拟赛day8
- 16.1117 NOIP 模拟赛
- [NOIP模拟赛]单词
- [NOIP模拟赛]玻璃杯
- [NOIP模拟赛]游戏
- c语言 清理字典文件 只保留可打印字符(包括空格)
- android 6.0禁用了权限却返回0
- eclipse 中提示tomcat 的端口被占用了 后的最快捷解决方法
- 学期末总结--by07/24?
- Robot Framework入门
- NOIP模拟赛 baoj2933数据
- 初学opencv/haar特征人脸检测
- Shell命令之将iOS的APP安装到模拟器中
- 【uva11732】"strcmp()" Anyone?
- (嵌入式)关于arm中的存储控制器(一)
- 在struts2框架中配置validate中出现404问题
- VIM列编辑
- 解决win10 composer xdebug 冲突
- [绍棠_swift] Swift中的继承、构造器