您的位置:首页 > 其它

code1135 选择客栈

2016-07-08 09:59 330 查看
首先,预处理三个数组。

pre[x]表示在此之前颜色为x的客栈有多少个。

f[x]表示在此之前的客栈中,某个点c,c的颜色为x,并且从c点到已经读入的点之间有费用小于p的客栈,这样的c点的个数

last[x]表示上一个颜色为x的客栈出现在哪

那么接下来的事情就很显然了。

首先读进去一个客栈,如果这个客栈满足费用小于等于p,就把它存下来,为temp(也就是说找到一个最近的费用满足题目要求的客栈)

接下来,如果客栈temp在上一个此颜色的客栈之后出现,那么就更新f[x]为pre[x]。(因为temp是满足费用的,那么在此之前所有颜色为x点pre[x]都能满足我们之前对点c的定义,所以都加入f数组)

每次ans+=f[x]。当前新读入的点的颜色为x,那么它与前面所有颜色为x且满足费用的(即f[x])都可以匹配,所以加入ans

最后,更新你的pre和last数组即可

代码:

#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define write(a) printf("%d\n",a);
#define REP(i,a,b) for (int i=(a);i<=(b);i++)
#define PER(i,a,b) for (int i=(a);i>=(b);i--)
#define N 200005
#define M 1000005
#define INF 1e9
using namespace std;
template <class T>
inline void read(T& num) {
bool start=0,neg=0;
char c;
num=0;
while ((c=getchar())!=EOF) {
if (c=='-') start=neg=1; else
if (c>='0' && c<='9') {
start=1;
num=num*10+c-'0';
} else if (start) break;
}
if (neg) num=-num;
}
/*===========Head Template================*/
int n,m,p;
int f
,pre
,last
;
int ans=0;
int main() {
read(n);read(m);read(p);
int x,y,tmp;
REP(i,1,n) {
read(x);read(y);
if (y<=p) tmp=i;
if (tmp>=last[x]) f[x]=pre[x];
ans+=f[x];
pre[x]++;
last[x]=i;
}
write(ans);
}


这应该也算dp吧,看来我见识的题还是太少了。。。

(我是不会告诉你这是抄的,不过上面的解释部分我自己补充了一下)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: