1 条题解
-
0
题目解析
题意分析
题目描述了一个图书馆的管理问题。我们需要处理一系列请求,目标是在处理完所有请求后,使的插入次数最少。具体规则如下: 有个驱动器,每个驱动器同一时间只能存放一张。 当请求的已经在某个驱动器中时,无需任何操作。 如果请求的不在任何驱动器中: 如果有空闲的驱动器,直接将插入。 如果没有空闲的驱动器,需要选择一个驱动器中的替换为当前请求的,此时插入次数加。 我们需要提前知道整个请求序列,并按照顺序处理请求,目标是使总插入次数最小。
解题思路
这是一个典型的缓存替换问题,类似于操作系统中的页面置换算法。最优策略是贪心算法中的**最远将来使用()**策略,即在需要替换时,选择当前缓存中未来最晚被请求的进行替换。
具体步骤如下: 初始化一个集合表示当前驱动器中的集合,初始为空。 遍历请求序列,对于每个请求: 如果已经在中,直接跳过。 如果不在中: 如果,将插入,插入次数加。 如果,需要选择一个替换: 遍历中的每个,找到在后续请求中最晚出现(或不再出现)的那个,将其替换为,插入次数加。 3. 最终输出总插入次数。
复杂度分析
- 对于每个测试用例,需要遍历个请求。
- 对于每个需要替换的请求,需要检查个驱动器中的,并在剩余请求中查找其下一次出现的位置。
- 最坏情况下,每次替换需要时间。
- 总复杂度为,由于且,完全可接受。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int inf = 0x7fffffff; int n, m, ans, op[105], pos[1000005]; bool exist[1000005]; int drive[15], temp[15]; //n为DVD drives数量 //m为操作数 int find(int opr) { int res = -1, opaa; for(int i = 1; i <= n; i++) { if(pos[op[drive[i]]] < opr) temp[i] = inf; else { for(int j = opr + 1; j <= m; j++) { if(op[drive[i]] == op[j]) { temp[i] = j; break; } } } } for(int i = 1; i <= n; i++) { if(res < temp[i]) { res = temp[i]; opaa = i; if(res == inf) break; } } return opaa; } void solve(int opr, int k) { //opr为操作数, k为正在使用的DVD drives编号 if(opr > m) return; if(k > n) { if(exist[op[opr]]) solve(opr + 1, k); else { ans++; int opaa = find(opr); exist[op[drive[opaa]]] = false; exist[op[opr]] = true; drive[opaa] = opr; solve(opr + 1, k); } } else { if(exist[op[opr]]) solve(opr + 1, k); else { exist[op[opr]] = true; ans++; drive[k] = opr; solve(opr + 1, k + 1); } } } int main() { int t; scanf("%d", &t); while(t--) { // 手动初始化 exist 数组 for (int i = 0; i < 1000005; ++i) { exist[i] = false; } // 手动初始化 drive 数组 for (int i = 0; i < 15; ++i) { drive[i] = 0; } // 手动初始化 temp 数组 for (int i = 0; i < 15; ++i) { temp[i] = 0; } // 手动初始化 pos 数组 for (int i = 0; i < 1000005; ++i) { pos[i] = 0; } // 手动初始化 op 数组 for (int i = 0; i < 105; ++i) { op[i] = 0; } ans = 0; scanf("%d%d", &n, &m); for(int i = 1; i <= m; i++) { scanf("%d", &op[i]); pos[op[i]] = max(pos[op[i]], i); } solve(1, 1); printf("%d\n", ans); } return 0; }
- 1
信息
- ID
- 1698
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者