当前位置: 首页 > news >正文

【递归完全搜索】USACO Bronze 2018 December - 往返搬运Back and Forth

题目描述

农夫约翰(Farmer John)有两个挤奶棚,每个棚中都有一个巨大的储奶罐,以及一个储物柜,里面各自装有 101010 个不同容量的水桶。他喜欢通过在两个棚之间运奶来锻炼身体。

星期一,农夫约翰分别在两个棚的储奶罐中各装入 1000 加仑的牛奶。

接下来的四天,他每天会进行如下操作:

  • 星期二:从第一个棚中拿出一个水桶,装满牛奶后带到第二个棚,把牛奶倒入第二个棚的储奶罐中,然后把水桶留在第二个棚。
  • 星期三:从第二个棚中拿一个水桶(可能是星期二留下的那个),装满牛奶后带到第一个棚,把牛奶倒入第一个棚的储奶罐中,然后把水桶留在第一个棚。
  • 星期四:从第一个棚中拿一个水桶(可能是前一天带回来的那个),装满牛奶后带到第二个棚,把牛奶倒入第二个棚的储奶罐中,然后把水桶留在第二个棚。
  • 星期五:从第二个棚中拿一个水桶(可能是前几天带过去的某个),装满牛奶后带到第一个棚,把牛奶倒入第一个棚的储奶罐中,然后把水桶留在第一个棚。

五天过后,农夫约翰测量了 第一个棚储奶罐中剩余的牛奶量。他想知道,这个值有多少种不同的可能?

输入格式

111 行:101010 个整数,表示第一个棚中水桶的容量。

222 行:101010 个整数,表示第二个棚中水桶的容量。

所有水桶的容量范围均为 111100100100

输出格式

输出一个整数,表示最终第一个棚储奶罐中 可能出现的不同牛奶量的个数

样例输入

1 1 1 1 1 1 1 1 1 2
5 5 5 5 5 5 5 5 5 5

样例输出

5

样例解释

最后,第一个棚的储奶罐可能出现如下 5 种牛奶量:

  • 1000:例如每次都用同一个桶来回搬运(1→5→1→5),刚好收支相抵。
  • 1003:星期二用 2 加仑的桶送出,星期三用 5 加仑的桶送回,星期四送出 1 加仑桶,星期五送回 1 加仑桶,净增加 3。
  • 1004:星期二送出 1,加回 5,再送 1,再加回 1,净增加 4。
  • 1007:送出 1,加回 5,送出 2,加回 5,净增加 7。
  • 1008:送出 1,加回 5,送出 1,加回 5,净增加 8。

提交链接

https://usaco.org/index.php?page=viewproblem2&cpid=857

思路分析

🧠 问题建模思路

🎯 目标

我们要确定在经过 444 天搬运过程(周二到周五)之后,第一个棚里的储奶罐可能剩下多少种不同的牛奶量。

🧩 问题简化与观察

这不是一个模拟题,而是一个穷举所有可能状态的组合问题。题目中的搬运方式遵循以下规律:

  • 每天搬运一次,共 444 天。

  • 每次搬运从当前棚中选一个桶,装满后带到另一个棚,将奶倒入后把桶留在那里。

  • 搬运顺序固定:

    • 周二:A → B
    • 周三:B → A
    • 周四:A → B
    • 周五:B → A

🧠 状态空间思考

这个问题的核心是 —— 在 444 步桶的移动中,不同的选择路径最终会导致不同的牛奶分布,尤其是第一个桶中的最终值。但每一步的决策都取决于当前棚中有哪些桶,所以状态的变化不仅包括奶量的变化,还包括桶的分布变化。

因此每一个状态应该包括:

  • 当前是第几天(day
  • 棚 A 的牛奶量(v_a
  • 棚 B 的牛奶量(v_b
  • 棚 A 当前的桶(a
  • 棚 B 当前的桶(b

每次我们从当前棚中拿一个桶,更新两个棚的桶列表,并转移相应的牛奶。

✅ 解题策略:DFS(深度优先搜索)

我们要枚举所有可能的“桶选择顺序”,每次从当前棚中任选一个桶进行搬运,更新状态后递归下一天。

❓ 为什么选择 DFS?

  • 每一步最多有 101010 个桶可选
  • 只递归 444 层(444 天)
  • 状态数量最多是 10410^4104 左右,可以接受

我们不关心路径本身,只关心最后的结果(第一棚的奶量),所以可以用一个 set 把所有最终结果记录下来。

🔄 状态转移逻辑

dfs(day, v_a, a, v_b, b) 中,我们表示当前是第 day 天,棚 A 有 v_a 单位奶,棚 B 有 v_b 单位奶。

每次递归时:

  • 当前是第 day 天,从当前棚(a)中枚举每一个桶:
    • 将这个桶从 a 移除,加入到 b
    • 将这个桶的容量对应的牛奶从 v_a 减去,加到 v_b
    • 然后递归下一天
    • 注意:此时 A 和 B 的角色互换(搬运是双向交替的)

我们用递归完成这个过程,直到 day == 4,表示搬运完了 4 次,此时把 v_a 记录到结果集合中。

📦 终止条件

day == 4,表示已经进行了 4 次搬运,此时记录第一个桶的牛奶量。

由于使用的是 set<int>,它会自动去重,记录所有不同的结果。

参考代码

#include <bits/stdc++.h>
using namespace std;
set<int> s;// 周几  从a-->b
void dfs(int day, int v_a, vector<int> a, int v_b, vector<int> b)
{if (day == 4){s.insert(v_a);return;}for (int i = 0; i < a.size(); i++){vector<int> a1 = a;a1.erase(begin(a1) + i);vector<int> b1 = b;b1.push_back(a[i]);dfs(day + 1, v_b + a[i], b1, v_a - a[i], a1);}
}
int main()
{// freopen("backforth.in", "r", stdin);// freopen("backforth.out", "w", stdout);vector<int> a(10), b(10);for (auto &it : a)cin >> it;for (auto &it : b)cin >> it;dfs(0, 1000, a, 1000, b);cout << s.size();return 0;
}
http://www.lryc.cn/news/614507.html

相关文章:

  • Python字典高阶操作:高效提取子集的技术与工程实践
  • RAG初步实战:从 PDF 到问答:我的第一个轻量级 RAG 系统(附详细项目代码内容与说明)
  • React 状态管理入门:从 useState 到复杂状态逻辑
  • React+TypeScript代码注释规范指南
  • HTML5 Web Workers 深度剖析:助力网页性能飞速提升
  • 3- Python 网络爬虫 — 如何抓取动态加载数据?Ajax 原理与实战全解析
  • 亚马逊广告运营如何平衡ASIN投放和关键词投放
  • 1688 图片搜图找货接口开发实战:从图像特征提取到商品匹配全流程
  • 塑料可回收物检测数据集-10,000 张图片 智能垃圾分类系统 环保回收自动化 智慧城市环卫管理 企业环保合规检测 教育环保宣传 供应链包装优化
  • 快速入门flask应用(从入门到实战)
  • 客户端攻击防御:详解现代浏览器安全措施
  • 彻底解决Hewlett-Packard - USB - 4/8/2019 12:00:00 AM - 1.0.0.237问题
  • 下一代防火墙技术
  • web端-登录页面验证码的实现(springboot+vue前后端分离)超详细
  • 《Graph machine learning for integrated multi-omics analysis》
  • 从C学C++(9)——运算符重载
  • 使用Python爬虫,selenium能否替代requests?
  • 利用哥斯拉(Godzilla)进行文件上传漏洞渗透实战分析
  • 爬虫逆向之雷池waf
  • 使用 PicGo 与 GitHub 搭建高效图床,并结合 Local Images Plus 备份原图
  • Kiro :从“规范”到“实现”的全流程 AI 助手
  • 线程池分析与设计
  • 豆包新模型+PromptPilot:AI应用开发全流程实战指南
  • 图片识别表格工具v3.0绿色版,PNG/JPG秒变可编辑Excel
  • 深入理解模板方法模式:框架设计的“骨架”艺术
  • Shell解释器
  • $QAXHoneypot是什么文件夹
  • 【入门级-C++程序设计:9、函数与递归-传值参数与传引用参数】
  • DMA伟大的数据搬运工
  • Dixon‘s 因子分解法——C语言实现