- 题解
拯救花园题解(贪心策略)
- @ 2026-7-24 14:52:12
问题理解
晨晨有 n 只兔子在花园里捣乱,每只兔子有两个属性:
tᵢ:把这只兔子送回笼子所需的时间(单程),来回一趟需要 2 × tᵢ 时间。
dᵢ:这只兔子每单位时间能破坏的花朵数。
送兔子的顺序可以任意选择。在送某只兔子的过程中(耗时 2tᵢ),其他所有尚未被抓的兔子会持续破坏花园。晨晨希望安排一个顺序,使得总破坏花朵数最小。
关键思路:贪心排序
这个问题不能用简单的“先抓破坏力大的”或“先抓耗时短的”来解决,因为两者相互制约。我们需要比较两只兔子谁更应该先抓。
假设只有两只兔子 A 和 B,考虑两种顺序:
先 A 后 B
送 A 时,B 还在破坏,破坏值 = d_B × 2t_A
送 B 时,已经没有其他兔子了,破坏值 = 0
总破坏 = d_B × 2t_A
先 B 后 A
送 B 时,A 还在破坏,破坏值 = d_A × 2t_B
总破坏 = d_A × 2t_B
哪种顺序更优?比较两个总破坏:
先 A 后 B 更优 ⇔ d_B × 2t_A < d_A × 2t_B
两边同时除以 2,得 d_B × t_A < d_A × t_B
移项得 d_A / t_A > d_B / t_B(注意 t 为正数)
结论:按照 dᵢ / tᵢ 从大到小排序,比值大的兔子应该先抓。为了避免浮点数误差,实际比较时使用交叉相乘:d_A × t_B > d_B × t_A则 A 排在 B 前面。
计算总破坏
排序后,我们按顺序送兔子。设当前还未被抓的兔子的破坏力总和为 sum(初始为所有 dᵢ 之和)。当送第 i 只兔子时:
耗时 2 × tᵢ
在此期间,其他 sum - dᵢ只兔子(即剩下所有兔子)一直在破坏
破坏增加 = (sum - dᵢ) × 2 × tᵢ
送完这只兔子后,从 sum 中减去它的 dᵢ,继续处理下一只。
样例验证
输入:
复制 6 3 1 2 5 2 3 3 2 4 1 1 6
先计算每只兔子的 d/t 比值(近似):
兔子1: 1/3 ≈ 0.33
兔子2: 5/2 = 2.5
兔子3: 3/2 = 1.5
兔子4: 2/3 ≈ 0.67
兔子5: 1/4 = 0.25
兔子6: 6/1 = 6
按比值降序:6 > 2 > 3 > 4 > 1 > 5,与样例顺序一致。
计算过程(sum 初始 = 1+5+3+2+1+6 = 18):
送6:耗时2×1=2,破坏 = (18-6)×2 = 24,sum=12
送2:耗时2×2=4,破坏 = (12-5)×4 = 28,sum=7
送3:耗时2×2=4,破坏 = (7-3)×4 = 16,sum=4
送4:耗时2×3=6,破坏 = (4-2)×6 = 12,sum=2
送1:耗时2×3=6,破坏 = (2-1)×6 = 6,sum=1
送5:耗时2×4=8,破坏 = (1-1)×8 = 0,sum=0
总破坏 = 24+28+16+12+6 = 86 ✅ 上一期代码
#include<bits/stdc++.h>
using namespace std;
int mp[6][6],vis[15][15],a[4]={1,0,-1,0},b[4]={0,1,0,-1};
int peth[255][2];
int n,m,ans;
char as[110][110];
void dfs(int x,int y,int step){
if(x==n&&y==m){
ans++;
cout<<ans<<":";
for(int i=0;i<step-1;i++){
cout<<peth[i][0]<<","<<peth[i][1]<<"->";
}
cout<<peth[step-1][0]<<","<<peth[step-1][1]<<endl;
}
for(int i=0;i<4;i++){
int xx=x+b[i];
int yy=y+a[i];
if(xx<=n&&xx>=1&&yy<=m&&yy>=1&&vis[xx][yy]==0&&as[xx][yy]=='o'){
peth[step][0]=xx;
peth[step][1]=yy;
vis[xx][yy]=1;
dfs(xx,yy,step+1);
vis[xx][yy]=0;
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>as[i][j];
}
}
vis[1][1]=1;
peth[0][0]=1;
peth[0][1]=1;
dfs(1,1,1);
if(ans==0) cout<<"no";
return 0;
}
老规矩,下一期将颁布代码,同时预告时间为2026.7.25,内容是高精度c++内容
2 条评论
-
liangzhuoran LV 10 @ 2026-7-24 14:53:58@wangyuanhang,本期怎样
-
@ 2026-7-24 14:52:47点个赞吧
- 1