书本转移

小强有 3 个箱子 A,B,C 用来装书,所有的书(一共n本)都按序号由小到大的顺序堆在 A上,现在他想把所有的书全都放到 C 里面去。每次他从 A 书架拿 a 本书(不够就全拿完)到 B,A 箱子翻转,然后从 B 拿 b 本书(不够就全拿完)到 C,B 箱子翻转。然后重复操作,直到所有书都到了 C,求最后的C 里面书的顺序,详细见样例。 输入描述: 输入由多组数据构成,每组数据占一行,3 个数,n(1<=n<=10^5),a(1<=a<=10^9) , b(1<=b<=10^9),含义见题目表述。以文件结尾。 输出描述: 每组数据输出一行,首先输出数据组数,然后输出 n 个数,C 中书的排列。


输入输出没有按照要求进行,主要过程经过简单测试


// bookmove.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
	long n = 10;
	long a = 1;
	long b = 1;

	printf("input n,a,b:");
	scanf("%d%d%d",&n,&a,&b);
	long cstart = 0;  //C 书本开始序号

	char aover = 0; //A 是否全部拿完 1完 0非
	char bover = 0; //B 是否全部拿完 1完 0非

	if(n <= a)
	{
		aover = 1;
	}
	if (aover)
	{
		//a全部拿完
		if (n <= b)
		{
			bover = 1;
		}

	}
	else
	{
		if (a <= b)
		{
			bover = 1;
		}

	}

	//对于aover bover讨论


	if (aover)
	{
		if (bover)
		{
			cstart = 1;
		} 
		else
		{
			cstart = n - b + 1;
		}
		
		
	}
	else
	{
		if (bover)
		{
			cstart = n - a + 1;
		} 
		else
		{
			cstart = n - b + 1;
		}

	}

	for (long i = cstart;i <= n;i++)
	{
		printf("%d\t",i);
	}
	printf("\n");
	getchar();




	return 0;
}





### C++ 实现书本整理算法 以下是对书本整理问题的详细分析和 C++ 实现。此问题的核心在于通过动态规划方法找到最优解,使得在移除指定数量的后,剩余书本之间的高度差最小化。 #### 问题描述 给定 `n` 本书,每本书有高度 `h` 和宽度 `w`,需要从中移除 `k` 本书,目标是使剩余书本的高度按升序排列,并且最小化相邻书本宽度之间的总差值。 --- #### 动态规划实现 以下是基于动态规划的 C++ 实现代码: ```cpp #include <bits/stdc++.h> using namespace std; #define MAXN 510 #define INF 1e9 int n, k, dp[MAXN][MAXN], m; struct Book { int h, w; } book[MAXN]; bool cmp(Book a, Book b) { return a.h < b.h; // 按高度升序排序 } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> k; m = n - k; // 剩余书本数量 for (int i = 1; i <= n; ++i) { cin >> book[i].h >> book[i].w; } sort(book + 1, book + 1 + n, cmp); // 按高度排序 // 初始化 dp 数组 memset(dp, 0x3f, sizeof(dp)); // 使用 INF 初始化 for (int i = 1; i <= n; ++i) { dp[i][1] = 0; // 只选择本书时,代价为 0 } // 动态规划填表 for (int i = 2; i <= n; ++i) { // 当前书本 for (int l = 2; l <= min(i, m); ++l) { // 当前分组数量 for (int j = 1; j < i; ++j) { // 枚举上本被选中的 dp[i][l] = min(dp[i][l], dp[j][l - 1] + abs(book[i].w - book[j].w)); } } } // 计算最终答案 int ans = INF; for (int i = m; i <= n; ++i) { ans = min(ans, dp[i][m]); } cout << ans << endl; return 0; } ``` --- #### 算法详解 1. **输入处理**: - 输入书本数量 `n` 和需要移除的书本数量 `k`。 - 每本书的高度 `h` 和宽度 `w` 存储在结构体数组中[^1]。 2. **排序**: - 将所有书本按照高度 `h` 升序排列,确保剩余书本的高度满足题目要求。 3. **动态规划状态定义**: - 定义 `dp[i][l]` 表示从前 `i` 本书中选择 `l` 本书,并以第 `i` 本书作为最后本书时的最小宽度差值[^2]。 4. **状态转移方程**: - 对于每本书 `i`,枚举所有可能的分组数量 `l` 和上本被选中的 `j`。 - 转移方程为: \[ dp[i][l] = \min(dp[i][l], dp[j][l-1] + |book[i].w - book[j].w|) \] - 这里 `|book[i].w - book[j].w|` 表示当前书本与上本被选中书本之间的宽度差值。 5. **初始化**: - 初始时,将 `dp` 数组的所有值设置为无穷(`INF`),表示未计算的状态。 - 特殊情况:当只选择本书时,宽度差值为 0,因此 `dp[i][1] = 0`。 6. **结果计算**: - 遍历所有可能的最后本书 `i`,并从 `dp[i][m]` 中选取最小值作为最终答案[^1]。 --- #### 时间复杂度分析 - 排序时间复杂度为 \(O(n \log n)\)。 - 动态规划填表的时间复杂度为 \(O(n^2 \cdot m)\),其中 \(n\) 是书本总数,\(m\) 是剩余书本数量。 - 总体时间复杂度为 \(O(n^2 \cdot m)\)。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值