USACO月赛题解 第三十讲 动态规划(一)
2014-02-01 14:09
267 查看
汇总见http://blog.csdn.net/qyl916/article/details/12442283
这五个DP题还是很不错的
第6题,方形牛棚 bigbrn
很经典的题目了,没有看题解,自己想了个解法
首先m较小的话可以参考另一篇博客,把点看成边界来做
这道题DP比较好一些
d[i][j]=min(d[i-1][j-1]+1,min( lft[i][j],up[i][j] ) );
lft和up分别表示左方和上方的空间,都能在平方级时间算出
d[i][j]表示以(i,j)为右下角顶点的边长最大值
因此整个算法是平方级的
第8题 滑雪比赛 bobsled
这题明显是贪心,分类到DP应该是因为用到递推的关系。两个转弯点之间必然是这样的策略:不停加速,直到另一个转弯点“刹不住”,这样就能列出不等式,解出这个区间的最大速度,同时更新下一个转弯点的速度(因为可能不停加速不用刹车).这样就能递推+计算答案了。
但这样做有漏洞:假如两个转弯点之间的距离为1,前一个限速10,后一个限速1,显然第一个点速度只能到2.所以要计算一个弯角的“真限速”,计算方法不难,枚举这个点后面的所有弯角,将这些弯角的限速加上两个弯角之间的距离就行了。什么?这样是平方级的?平方算法有大量重复计算,完全可以变成线性的。
这五个DP题还是很不错的
第6题,方形牛棚 bigbrn
很经典的题目了,没有看题解,自己想了个解法
首先m较小的话可以参考另一篇博客,把点看成边界来做
这道题DP比较好一些
d[i][j]=min(d[i-1][j-1]+1,min( lft[i][j],up[i][j] ) );
lft和up分别表示左方和上方的空间,都能在平方级时间算出
d[i][j]表示以(i,j)为右下角顶点的边长最大值
因此整个算法是平方级的
void setio(string name){ string in_f=name+".in"; string out_f=name+".out"; freopen(in_f.c_str(),"r",stdin); freopen(out_f.c_str(),"w",stdout); } const int maxn=1010; int d[maxn][maxn],lft[maxn][maxn],up[maxn][maxn],a[maxn][maxn],n,m; int main() { setio("bigbrn"); CLR(a,0); read2(n,m); REP(i,m){ int x,y; read2(x,y); a[x][y]=1; } CLR(lft,0);CLR(up,0); REP1(i,n)lft[i][1]=a[i][1]==1?-1:0; REP1(i,n)FOR(j,2,n){ lft[i][j]=a[i][j]==1?-1:lft[i][j-1]+1; } REP1(j,n)lft[1][j]=a[1][j]==1?-1:0; FOR(i,2,n)REP1(j,n){ up[i][j]=a[i][j]==1?-1:up[i-1][j]+1; } CLR(d,0); int ans=0; REP1(i,n)REP1(j,n){ d[i][j]=min(d[i-1][j-1]+1,min( lft[i][j],up[i][j] ) ); ans=max(ans,d[i][j]); } /*REP1(i,n){REP1(j,n)write1(lft[i][j]);PN;}PN; REP1(i,n){REP1(j,n)write1(up[i][j]);PN;}PN; REP1(i,n){REP1(j,n)write1(d[i][j]);PN;}*/ writeln(ans+1); //system("pause"); return 0; }
第8题 滑雪比赛 bobsled
这题明显是贪心,分类到DP应该是因为用到递推的关系。两个转弯点之间必然是这样的策略:不停加速,直到另一个转弯点“刹不住”,这样就能列出不等式,解出这个区间的最大速度,同时更新下一个转弯点的速度(因为可能不停加速不用刹车).这样就能递推+计算答案了。
但这样做有漏洞:假如两个转弯点之间的距离为1,前一个限速10,后一个限速1,显然第一个点速度只能到2.所以要计算一个弯角的“真限速”,计算方法不难,枚举这个点后面的所有弯角,将这些弯角的限速加上两个弯角之间的距离就行了。什么?这样是平方级的?平方算法有大量重复计算,完全可以变成线性的。
/* 40分 没考虑刹不住的问题 120分 三个小数据不对 仔细一看,终点速度没有算 还是错一个点 大数据出错,INF太小 */ const LL INF = (LL)1<<50; struct node{ LL t,s; }; int cmp(node a, node b){ return a.t < b.t; } void setio(string name){ string in_f = name + ".in"; string out_f = name + ".out"; freopen(in_f.c_str(), "r", stdin); freopen(out_f.c_str(), "w", stdout); } node a[100010]; LL d[100010],m[100010],n,l; int main() { setio("bobsled"); scanf("%lld%lld",&l,&n); REP1(i,n) scanf("%lld%lld",&a[i].t,&a[i].s); sort(a + 1, a + n + 1, cmp); a[0].t = 0; a[0].s = 1; a[n + 1].t = l; a[n + 1].s = INF; m[n + 1] = INF; for(LL i = n; i >= 0; i--) m[i]=min(m[i + 1], a[i].s + a[i].t); LL ans = 0; d[0]=1; REP1(i,n){ d[i] = min(min(a[i].s, d[i-1] + a[i].t - a[i - 1].t), m[i + 1] - a[i].t); ans = max(ans, (a[i].t - a[i - 1].t + d[i] - d[i - 1] ) / 2 + d[i - 1] ); } ans = max(ans, d + l - a .t); cout<<ans<<endl; //while(1); return 0; }
相关文章推荐
- win8 驱动签名
- spoj 6779. Can you answer these queries VII(树链剖分)
- 动态规划2:最大子段和问题到最大子矩阵问题(二):最大n子段和问题详谈
- USACO月赛题解 第四讲 数值计算
- 使用国内的WSUS服务
- 【题解】【DP】【Leetcode】Climbing Stairs
- unity3d 多语言 解决方案1——自定义本地文本
- Asynchronous calls and remote callbacks using Lingo Spring Remoting
- 关于Unity3D中Resources动态加载NGUI图片的方法!!!
- Lingo (Spring Remoting) : Passing client credentials to the server
- uva 1146(2-SAT+二分判断)
- 网站后台admin修改故事
- begin linux programming
- hibernate配置信息
- 文字特效 Text Fx插件学习记录
- setTimeout 最终版本 面向对象可扩展
- tabhost,framelayout,tabwidget(一)
- 超简代码版设计模式系列十四
- 18-Linux-网络配置
- do {...} while (0) 的用途汇总(欢迎补充)