首页 > 其他 > 详细

[LuoguP2948][USACO09OPEN]Ski Lessons G

时间:2020-12-02 09:48:52      阅读:25      评论:0      收藏:0      [点我收藏+]

P2948 [USACO09OPEN]Ski Lessons G

前言

? 我已经很久很久,很久很久,没有只依靠自己想出一个DP了。开心。

Solution

? 首先设计一下状态,\(f_{i,j}\) 表示在时间 i ,能力值为 j 的时候能滑的最多场数。

? 接下来考虑在第 i 秒能干什么。有以下选项:

  • 啥也不干,于是 \(f_{i+1,j}\) 可以被 \(f_{i,j}\) 更新

  • 上一节课,\(f_{i+L_k,A_k}\) 可以被 \(f_{i,j}\) 更新,\(k\) 为一个在 i 时间开始的课程。

  • 滑一场雪,\(f_{i+D_k,j}\) 可以被 \(f_{i,j}\) 更新,\(k\) 为一个滑雪场。

    ? 但是现在时间复杂度很显然不对,到达了 \(O(TVN)\) 的级别,其中 \(V\) 为能力值域。

    ? 问题在于枚举一个滑雪场过于冗杂。观察到一个滑雪场可以滑多次,这启发我们贪心,对于一切以当前能力值可以滑的场,总是从中选一个耗时最小的来滑。就可以省去枚举。

    ? 而这个耗时最小的场既可以用数据结构维护也可以提前预处理,此处我选择预处理,预处理时间复杂度为\(O(NV)\),总的时间复杂度在 \(O(VN+TV+VS)\), \(VS\) 是因为每堂课会被枚举V次。

    ? 初始化为 \(f_{0,1}=0\),其余负无穷。

    CODE

    #define fe(i,a,b) for(int i=a;i<=b;++i)
    #define pii pair<int,int>
    #define mp(a,b) make_pair(a,b)
    const int inf=1e9;
    int t,s,n,minn[105],f[20005][105],ans;
    vector< pii > cl[10005];
    inline int M_min(int a,int b){return a<b?a:b;}
    inline int M_max(int a,int b){return a>b?a:b;}
    int main(){
    	t=read(),s=read(),n=read();
    	fe(i,0,100)minn[i]=inf;
    	fe(i,1,s){
    		int x=read(),y=read(),z=read();
    		cl[x].push_back(mp(y,z));
    	}
    	fe(i,1,n){
    		int c=read(),d=read();
    		fe(j,c,100)minn[j]=M_min(minn[j],d);
    	}
    	memset(f,-0x3f,sizeof(f));
    	f[0][1]=0;
    	fe(i,0,t){
    		int u=cl[i].size();
    		fe(j,0,100)if(f[i][j]>=0){
    			ans=M_max(ans,f[i][j]);
    			fe(k,0,u-1)f[i+cl[i][k].first][cl[i][k].second]=M_max(f[i][j],f[i+cl[i][k].first][cl[i][k].second]);
    			f[i+1][j]=M_max(f[i+1][j],f[i][j]);
    			if(i+minn[j]<=t)f[i+minn[j]][j]=M_max(f[i+minn[j]][j],f[i][j]+1);
    		}
    	}
    	printf("%d",ans);
    	return 0;
    }
    

[LuoguP2948][USACO09OPEN]Ski Lessons G

原文:https://www.cnblogs.com/clockwhite/p/14071809.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!