题目链接:http://codeforces.com/problemset/problem/500/C
题意:有n天,一共有m本书,每一本书有各自的重量,每一天要看一本书(n可以>m,就是可以多天看同一本),放书的地方像一个栈,假如要取第二本书的话,必须将第一本书拿出来,最后将当天看完的书放在顶端,问如何摆放使得举起的重量最小
思路:因为每次看完的书都必须放在顶端,每一次取书都必须承受之前看过的书的质量,因此应该按照书第一次出现的顺序来摆放,假设看书的顺序是a,b,书的摆放位置是b,a就需要额外承受多一次b的质量
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#define maxn 1530
using namespace std;
int w[maxn],b[maxn],vis[maxn];
stack <int> s;
int main()
{
int n,m;
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(vis,0,sizeof(vis));
while (!s.empty()) s.pop();
for (int i=1;i<=n;i++)
{
scanf("%d",&w[i]);
}
stack <int> tem;
for (int j=0;j<m;j++)
{
scanf("%d",&b[j]);
if (vis[b[j]]==0)
{
vis[b[j]]=1;
tem.push(b[j]);
}
}
while(!tem.empty())
{
int t=tem.top();
s.push(t);
tem.pop();
}
int res=0;
for (int i=0;i<m;i++)
{
while (s.top()!=b[i])
{
int t=s.top();
res+=w[t];
tem.push(t);
s.pop();
}
s.pop();
while(!tem.empty())
{
int t=tem.top();
s.push(t);
tem.pop();
}
s.push(b[i]);
}
printf("%d\n",res);
}
}