NOIP 2014飞扬的小鸟(DP优化)
题目链接 飞扬的小鸟
考场的70分暴力(实际只有50分因为数组开小了……)
考场代码(数组大小已修改)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define LL long long
#define fi first
#define se second const int INF = << ;
const int N = + ;
const int M = + ; int dp[M][N], x[N], y[N], u[N], d[N];
int n, m, q, ans, xn, ln, rn, _max, pos;
bool c[N]; int main(){ scanf("%d %d %d ", &n, &m, &q);
rep(i, , n - ) scanf("%d %d ", x + i, y + i);
rep(i, , n) u[i] = m, d[i] = ;
memset(c, false, sizeof c);
rep(i, , q){
scanf("%d %d %d ", &xn, &ln, &rn);
c[xn] = true;
u[xn] = rn - ;
d[xn] = ln + ;
}
//rep(i, 0, n) printf("%d %d\n", d[i], u[i]);
memset(dp, 0xff70, sizeof dp);_max = dp[][];
rep(i, , m) dp[][i] = ;
rep(i, , n - ){
rep(j, d[i], u[i]){
if (dp[i][j] >= _max) continue;
int k = j - y[i];
if (k >= && k <= m) dp[i + ][k] = min(dp[i + ][k], dp[i][j]);
k = j;int num = ;
while (true){
k += x[i]; ++num;
if (k > m) k = m;
if (k >= && k <= m) dp[i + ][k] = min(dp[i + ][k], dp[i][j] + num);
if (k == m) break;
}
}
} ans = _max;
rep(i, , m) ans = min(ans, dp[n][i]);
if (ans < _max){
printf("%d\n%d\n", , ans);return ;
} bool flag = false;
ans = ;
dec(i, n, ) {rep(j, , m) if (dp[i][j] < _max) { pos = i - ;flag = true; break;} if (flag) break;}
dec(i, pos, ) if (c[i]) ++ans;
printf("%d\n%d\n", , ans); return ;
}
然后回过来想正解。
其实我们把很多时间都浪费在这里了:
while (true){
k += x[i]; ++num;
if (k > m) k = m;
if (k >= && k <= m) dp[i + ][k] = min(dp[i + ][k], dp[i][j] + num);
if (k == m) break;
}
其实这一步可以转过来直接利用完全背包的性质优化一下。转移只要O(1)就可以了。
这道题细节还是很多的,比较容易写挂。
正解:
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) const int INF = << ;
const int N = + ;
const int M = + ; int dp[N][M], x[N], y[N], u[N], d[N];
int n, m, q, ans, xn, ln, rn, _max, pos;
bool c[N]; int main(){ scanf("%d %d %d ", &n, &m, &q);
u[n] = m + ; d[n] = ;
rep(i, , n - ) scanf("%d %d ", x + i, y + i), u[i] = m + , d[i] = ; rep(i, , q){
scanf("%d %d %d ", &xn, &ln, &rn);
u[xn] = rn;
d[xn] = ln;
} rep(i, , n + ) rep(j, , m + ) dp[i][j] = INF; rep(i, , m) dp[][i] = ;
rep(i, , n){
rep(j, x[i - ], m){
dp[i][j] = min(dp[i][j], dp[i - ][j - x[i - ]] + );
dp[i][j] = min(dp[i][j], dp[i][j - x[i - ]] + );
} rep(j, m - x[i - ], m){
dp[i][m] = min(dp[i][m], dp[i - ][j] + );
dp[i][m] = min(dp[i][m], dp[i][j] + );
} rep(j, d[i] + , u[i] - ){
if (j + y[i - ] <= m) dp[i][j] = min(dp[i][j], dp[i - ][j + y[i - ]]);
} rep(j, , d[i]) dp[i][j] = INF;
rep(j, u[i], m) dp[i][j] = INF;
} ans = INF;
rep(i, , m) ans = min(ans, dp[n][i]);
if (ans != INF) return , printf("%d\n%d\n", , ans);
int t = q;
dec(i, n, ){
rep(j, , m) ans = min(ans, dp[i][j]);
if (ans != INF) break;
if (u[i] != m + ) --t;
} printf("%d\n%d\n", , t);
return ;
}
NOIP 2014飞扬的小鸟(DP优化)的更多相关文章
- NOIp 2014飞扬的小鸟【dp】By cellur925
题目传送门 放在14年Day1T3的dp题目...应该比较看出来是dp算法吧,因为在本蒟蒻看来求最值的算法不清晰时就是dp了==. 状态还是比较好设计的,考虑到每个情况需要记录下的量:f[i][j]表 ...
- [NOIp 2014]飞扬的小鸟
Description Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉 ...
- 飞扬的小鸟 DP
飞扬的小鸟 DP 细节有点恶心的DP,设\(f[i][j]\)表示横坐标为\(i\)(从\(0\)开始)高度为\(j\)时,屏幕点击的最小次数为\(f[i][j]\),转移便很好写了,这里要注意枚举当 ...
- [NOIP2014]飞扬的小鸟[DP]
[NOIP2014]飞扬的小鸟 ——!x^n+y^n=z^n 题目描述: Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...
- NOIP 提高组 2014 飞扬的小鸟(记录结果再利用的DP)
传送门 https://www.cnblogs.com/violet-acmer/p/9937201.html 参考资料: [1]:https://www.luogu.org/blog/xxzh242 ...
- P1941 飞扬的小鸟[dp]
题目描述 Flappy Bird是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣 ...
- NOIP2014飞扬的小鸟[DP][WRONG]
坑人啊朴素的dp 75分 用了完全背包才是80分,结果普遍偏小 为什么啊啊啊啊啊 等以后再写一遍吧 #include<iostream> #include<cstdio> #i ...
- luogu1941 [NOIp2014]飞扬的小鸟 (dp)
设f[i][j]为到达(i,j)这个位置的最小操作数 就有$f[i][j]=min\{f[i-1][j+Y[i-1]],f[i-1][j-X[i-1]*k]+k\}$ 然后考虑优化一下转移: 对于一系 ...
- NOIP 2014
Prob.1 生活大爆炸版 石头剪刀布 模拟.代码: #include<cstdio> #include<cstring> #include<iostream> u ...
随机推荐
- Codeforces Round #464 (Div. 2) A Determined Cleanup
A. Love Triangle time limit per test1 second memory limit per test256 megabytes Problem Description ...
- [GDOI2016][树链剖分+主席树]疯狂动物城
题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...
- 有三个线程T1 T2 T3,如何保证他们按顺序执行
T3先执行,在T3的run中,调用t2.join,让t2执行完成后再执行t3 在T2的run中,调用t1.join,让t1执行完成后再让T2执行 public class JoinTest { ...
- navicat常用快捷键及注意事项
常用快捷键: 1. ctrl + q: 打开新查询窗口 2. ctrl + r: 运行当前窗口内的所有语句 3. ctrl + w: 关闭当前窗口 4. F6: 打开一个mysql命令行窗口 ---- ...
- Django 四——ModelForm用法
内容概要: 1.新增数据库表中数据 2.更新数据库表中数据 Django的ModelForm Django中内置了Form和Model两个类,有时候页面的表单form类与Model类是一一对应,因此分 ...
- Leetcode 518.零钱兑换II
零钱兑换II 给定不同面额的硬币和一个总金额.写出函数来计算可以凑成总金额的硬币组合数.假设每一种面额的硬币有无限个. 注意: 你可以假设 0 <= amount (总金额) <= 500 ...
- POJ 3494 Largest Submatrix of All 1’s 单调队列||单调栈
POJ 3494 Largest Submatrix of All 1’s Description Given a m-by-n (0,1)-matrix, of all its submatrice ...
- grep_awk_sed文本处理
小技巧 1.删除0字节文件find -type f -size 0 -exec rm -rf {} \; 2.查看进程按内存从大到小排列ps -e -o “%C : %p : %z : %a”|sor ...
- windows api 程序
#include "StdAfx.h" #include<windows.h> #include<mmsystem.h> LRESULT CALLBACK ...
- input上传多张图片
input的file上传多张图片的时候,用ajaxupload这个插件的时候,每次执行完,需要重新生成元素再绑定事件