New Year Book Reading E
题面:
题目大意:
小明打算在假期读书,他有n本书,第i本书有重量wi,给出小明读书的顺序,求怎么摆放一开始的书,使得小明读完书后,累计搬起的重量为最小值,并输出。
有以下规则:
- 当小明要拿一本书时,他要举起的重量是这本书上面的全部书的重量。
- 当小明看完一本书的时候,他会把书放在所有书的最上面。
思路:
一开始看这题是有点蒙的,但是你拿样例来模拟一下,就能发现,这其实也是有一点规律的。
首先我们划出一个分界线,上面是空的,下面是所有的书(不用理会顺序),然后我们拿第一本的时候,肯定它如果在下面的第一个重量是最少的,拿第二本时,如果它在分界线下面,那么它是分界线下面的第一本的话,需要抬起的重量是分界线上面的书,也就是重量最少的选择,如果在上面的话,因为上面顺序已经定了,所以直接模拟拿书过程就行,那么可以知道,一开始书的顺序其实是这本书第一次出现的顺序,比如
1 3 1 2 2 3 1最先出现的顺序是1->3->2,可以开个vis标记一下,其他的过程模拟拿书过程就行。
代码如下:
#include <iostream>
#include <cstdio>
#include<cstring>
using namespace std;
#define MAX 505
struct Node{
int w;
int i;
}x[MAX];
int vis[MAX];
int n,m;
int w[MAX];
long long ans;
int main()
{
scanf("%d %d",&n,&m);
for(int i = 1;i<=n;i++)
{
scanf("%d",&w[i]);
}
int sum = 0,k = 0;
for(int i = 0;i<m;i++)
{
int temp;
scanf("%d",&temp);
if(vis[temp])
{
Node a;
for(int j = 0;j<k;j++)
{
if(x[j].i == temp)
{
a = x[j];
while(j<k-1)
{
x[j] = x[j+1];
ans+=x[j].w;
j++;
}
}
}
x[k-1] = a;
}
else
{
ans+=sum;
vis[temp] = 1;
x[k].w = w[temp];
x[k].i = temp;
sum+=w[temp];
k++;
}
}
printf("%lld",ans);
return 0;
}