主页
搜索
最近更新
数据统计
赞助我们
系统公告
1
/
1
请查看完所有公告
你说得对,但我会剪枝
最后更新于 2025-06-16 07:23:51
作者
piantouqu
分类
题解
题解
AT_abc410_e
复制 Markdown
查看原文
更新内容
~~vp 时写出来的抽象东西,大家当乐子看就好。~~ ## 思路 容易想到 ```cpp memset(f,-1,sizeof f); f[h][m]=0; rep(i,1,n){ cin>>a>>b; dep(j,h,0) dep(k,m,0){ if(f[j][k]==i-1&&(j>=a||k>=b)){ ans=i; if(j>=a) f[j-a][k]=i; if(k>=b) f[j][k-b]=i; } } } ``` 但是时间复杂度是 $O(n^3)$ 的,显然超时。 我们考虑去剪枝: 1. 当 $f_{j,k}=1$ 时,再去减小 $j$ 或 $k$ 显然不会比当前更优。 2. memset 太慢了,我们特判 $n=1$ 的情况。 3. 当 $ans \ne i$ 时,我们可以直接 break 了。 剪完后的代码如下: ```cpp int mk=0,a,b; rep(i,1,n){ cin>>a>>b;mk=0; if(i==1){if(h>=a) f[h-a][m]=i,ans=i;if(m>=b) f[h][m-b]=i,ans=i;}//特判 i=1 的情况 dep(j,h,0) dep(k,m,max(0,mk)){//减小 j 显然不会比当前更优。 if(f[j][k]==i-1&&(j>=a||k>=b)){ ans=i; if(j>=a) f[j-a][k]=i,mk=k; if(k>=b) f[j][k-b]=i,mk=k-b; break;//减小 k 显然不会比当前更优。 } } if(ans!=i) break;//已经杀不死怪物了(悲 } cout<<ans; ``` 但还是 TLE 了。 此时好像没有什么可以优化的了,但是如果你去输出可行的 $j$ 和 $k$,可以发现后面的上界时不到 $h$ 和 $m$ 的。 所以我们去记录本次出现的最大的 $j$ 和 $k$,并用其对 $h$ 和 $m$ 更新。 优化完后,我们就可以 [AC](https://atcoder.jp/contests/abc410/submissions/66802185) 了(喜提最劣解)。
正在渲染内容...
点赞
0
收藏
0