[USACO2009 OPEN] 滑雪课 Ski Lessons
2024-10-07 08:06:10
看到题目就觉得这是动规但一直没想到如何状态转移……看了别人的题解之后才有一些想法
f[i][j]:前i单位时间能力值为j可以滑的最多次数
lessons[i][j]:结束时间为i,获得能力为j的时长最短的课程的开始时间
ski[i]:能力值为i可以滑的时间最短的坡的时长
d[i]表示前i时长最多可以滑的坡数
几个状态转移方程:
喝可可:f[i][j]=max(f[i][j],f[i-1][j])
滑雪:f[i][j]=max(f[i][j],f[i-ski[j]][j]+1)
上课:f[i][j]=max(f[i][j],d[lessons[i-1][j]])
随手贴个代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int lessons[][],ski[],f[][],d[];
//lessons[i][j]表示结束时间为i,能力为j的课程的最晚开始时间
//ski[i]表示能力值为i可以滑的时间最短的坡的时长
//f[i][j]表示前i时长能力值为j最多可以滑的坡数
//d[i]表示前i时长最多可以滑的坡数
int t,s,n;
int main()
{
scanf("%d%d%d",&t,&s,&n);
for(int i=;i<=s;i++)//初始化lessons[][]
{
int m,l,a;
scanf("%d%d%d",&m,&l,&a);
lessons[l+m-][a]=max(lessons[l+m-][a],m);
}
for(int i=;i<=n;i++)//初始化ski[]
{
int c,d;
scanf("%d%d",&c,&d);
for(int j=c;j<=;j++)
if(!ski[j]||ski[j]>d)
ski[j]=d;
}
for(int i=;i<=t;i++)
for(int j=;j<=;j++)
f[i][j]=-;
f[][]=;
for(int i=;i<=t;i++)
{
for(int j=;j<=;j++)
{
f[i][j]=max(f[i][j],f[i-][j]);//喝可可
if(ski[j]&&i>=ski[j])//滑雪
f[i][j]=max(f[i][j],f[i-ski[j]][j]+);
if(lessons[i-][j])//上课
f[i][j]=max(f[i][j],d[lessons[i-][j]]);
d[i]=max(d[i],f[i][j]);
}
}
printf("%d\n",d[t]);
return ;
}
注意两个问题:
1、初始化:f[0][1]=0(初始化能力为1),其余都为负无穷!
2、状态转移方程没有f[i][j]=max(f[i][j],f[i][j-1)!
第一次写的时候因为这两个问题WA了……但自己也没想出来为什么……如果有神犇理解的话敬请指教w
最后吧分享一句关于动规挺有感触的一句话……
除了要对基本概念和方法正确理解外,必须具体问题具体分析处理,以丰富的想象力去建立模型,用创造性的技巧去求解
(新人第一次发帖,多多指教)
最新文章
- Aptana Studio 3 汉化简体中文版
- 自定义右键菜单中bug记录
- [iOS 主要框架的总结]
- COLORBOX文档
- Java高效读取大文件
- 有趣的TWinControl.RecreateWnd,并分析在哪些场合使用
- Spring学习之Ioc控制反转(2)
- Selenium+Python之163邮件发送
- 详解go语言的array和slice 【二】
- EM vs REM vs PX,为什么你不应该”只用px“”
- MongoDB之基本操作与日常维护
- 【English】四、Y结尾名词变复数
- 【转载】Druid 介绍及配置
- SLG手游Java服务器的设计与开发——架构分析
- 专注笔试算法20年(C语言版)
- 2018.11.01 bzoj4872: [Shoi2017]分手是祝愿(期望dp)
- 读书笔记 C# 控制台应用程序之Main方法浅析
- Web标准:三、二列和三列布局
- 天梯赛L2-008 最长对称子串 (字符串处理)
- HDU 1166 【线段树 || 树状数组,单点修改 维护区间和】