Servicing DVD Requests
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 1734 Accepted: 509
Description
You are running a DVD library. Suppose that you have k DVD drives, through which the users can access the contents of the requested DVDs.A DVD drive can only access the content of one DVD at the same time. When a DVD request arrives, if the DVD is already in a DVD drive, then nothing needs to be done. Otherwise, you are supposed to insert the requested DVD into an empty drive. If all k drives are occupied, you have to remove a DVD out of the drive before having the requested DVD inserted into the drive. The objective is to minimize the number of DVD insertions required for serving the whole sequence of requests.
To make things interesting, we assume that you are given the whole sequence x1, x2, … , xn in advance. Also, you have to service request xi before servicing xi+1, for each i = 1, 2, … , n - 1. You want to carefully plan how to service each request such that the overall number of DVD insertions is minimized. Clearly, the difficulty lies in determining which DVD should be removed from its drive when you receive a request to a DVD not in any drive and all drives are occupied.
For example, let k = 2, and let the sequence of requests be 1, 2, 3, 1, 3, 1, 3. For the first two requests, one can simply put DVDs 1 and 2 into the drives. When the third request (i.e., DVD 3) arrives, you have to either remove DVD 1 or DVD 2 out of its drive so that DVD 3 can be inserted to a drive.
If you choose the first option (i.e., removing DVD 1), then the remaining requests (i.e., requests 4-7) need at least one more DVD insertions.
If you choose the second option (i.e., removing DVD 2), then the remaining requests (i.e., requests 4-7) need no more DVD insertions.
It is not difficult to verify that the second option results in an optimal way to service the above sequence of requests which needs only three DVD insertions.
Input
The first line contains the number m of test cases. Each test case starts with a line containing two numbers k and n, where 1 <= k <= 10 is the number of DVD drives and 1 <= n <= 100 is the number of requests. In the following n lines, the i-th line contains the i-th request xi.
Output
For each test case, your program has to output the minimum number of DVD insertions required to service the whole sequence of requests in one line.
Sample Input
2
2 7
1
2
3
1
3
1
3
3 9
1
2
3
4
1
2
1
2
4
Sample Output
3
4
定义
最佳(Optimal)置换算法是指,其所选择的被淘汰页面,将是以后永不使用的,或许是在最长(未来)时间内不再被访问的页面。采用最佳置换算法,通常可保证获得最低的缺页率。但由于人们目前还无法预知一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,因而该算法是无法实现的,但可以利用该算法去评价其它算法。
原先我以为是最优的选择是后面需要插入DVD最少次数的,想错了,想了想,确实是,如果离得近的话,你刚拆下来就得马上装回去
7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1这组数据挺好的,答案是9,一下验出了我代码的bug
//算法出现错误,因为我考虑的是拆卸的是后面操作最少的,但应该是最远时间操作的,如果你刚拆卸完马上就又要在装载上,像我那样想绝对不是最优的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100005
#define MAXN 0x3f3f3f3f
int p[N];//记录下一个这样的DVD的位置
typedef struct Node{
int x,y;
}Node;
bool cmp(const Node &a,const Node &b)
{
return a.y > b.y;
}
int main()
{
int m;
cin >> m;
int k,n;
int a[105];
int b[N];//记录第a[i]个DVD,每次都前一个的位置;
while(m--)
{
memset(b,-1,sizeof(b));
memset(p,MAXN,sizeof(p));
cin >> k >> n;
for(int i = 0;i < n;++i)
{
scanf("%d",&a[i]);
if(b[a[i]] == -1){
b[a[i]] = i;
}
else{
p[b[a[i]]] = i;
b[a[i]] = i;
}
}
/*for(int i = 0;i < n; ++ i)
{
cout << p[i] << " ";
}
cout << endl;*/
int num = 0;
bool flag[N] = {false};
Node res[11];
int now = 0;
for(int i = 0;i < n;++i)
{
if(now < k){
if(!flag[a[i]]){
res[now].x = a[i];
res[now++].y = p[i];
flag[a[i]] = true;
num++;
}
else{
for(int j = 0;j < k;++j)
{
if(res[j].x == a[i])
{
res[j].y = p[i];
break;
}
}
}
}
else{
if(!flag[a[i]]){
sort(res,res + k,cmp);
/*for(int j = 0;j < k;++j)
{
cout << res[j].x << " ";
}
cout << endl;*/
flag[res[0].x] = false;
flag[a[i]] = true;
num++;
res[0].x = a[i];
res[0].y = p[i];
}
else{
for(int j = 0;j < k;++j)
{
if(res[j].x == a[i])
{
res[j].y = p[i];
break;
}
}
}
}
}
cout << num << endl;
}
return 0;
}