码迷,mamicode.com
首页 > 其他好文 > 详细

code1135 选择客栈

时间:2016-07-08 10:05:41      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

首先,预处理三个数组。

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[N],pre[N],last[N];
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吧,看来我见识的题还是太少了。。。

(我是不会告诉你这是抄的,不过上面的解释部分我自己补充了一下)

code1135 选择客栈

标签:

原文地址:http://www.cnblogs.com/FuTaimeng/p/5652377.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!