• 题解 POJ3171 【Cleaning Shifts】


    题目链接:Link

    Problem

    Solution

    一个很直观的想法是设 $ f(x) $ 表示覆盖[L,x]需要花费的最小代价。
    为避免后效性,可将奶牛右端点排序。设当前奶牛为 $ [L,R],c $ ,则状态转移方程为:

    [f(R) = minlimits_{L-1 le x le R} { f(x) } + c ]

    观察到这个dp过程事实上是在不断地在f数组里求区间最小值、单点修改,用线段树维护即可。

    Code

    #include<cstdio>
    struct char_reader
    {
    	FILE* f; char *buf,*p1,*p2; int size;
    	char_reader(FILE* fin,int bufsize=1000000) { f=fin; size=bufsize; p1=p2=0; buf=new char[bufsize]; }
    	inline int operator()() { return p1==p2&&(p2=(p1=buf)+fread(buf,1,size,f),p1==p2)?EOF:*p1++; }
    };
    struct char_writer
    {
    	FILE* f; char *buf,*p,*end;
    	char_writer(FILE* fout,int bufsize=1000000) { f=fout; buf=new char[bufsize]; p=buf; end=buf+bufsize; }
    	~char_writer() { fwrite(buf,p-buf,1,f); }
    	inline char operator()(char ch) { return end==p&&(fwrite(buf,end-buf,1,f),p=buf),*p++=ch; }
    };
    char_reader gch(stdin);
    char_writer wch(stdout);
    template<typename T> inline void read(T& t)
    {
    	t=0; bool f=false; char ch;
    	while(ch=gch(),!((ch>='0'&&ch<='9')||ch=='-'));
    	if(ch=='-') f=true,ch=gch();
    	t=ch-'0';
    	while(ch=gch(),ch>='0'&&ch<='9') t=t*10+ch-'0';
    	if(f) t=-t;
    }
    template<typename T> inline void write(T t)
    {
    	int stk[20],cnt=0;
    	if(t==0) { wch('0'); return; }
    	if(t<0) { wch('-'); t=-t; }
    	while(t>0) { stk[cnt++]=t%10; t/=10; }
    	while(cnt) wch(stk[--cnt]+'0');
    }
    inline void write(char t) { wch(t); }
    inline void write(const char *&s) { while(*s) wch(*s++); }
    #if __cplusplus >= 201103L
    template<typename T,typename... Args> inline void read(T& t,Args&... args) { read(t); read(args...); }
    template<typename T,typename... Args> inline void write(T t,Args... args) { write(t); write(args...); }
    #else
    template<typename A_t,typename B_t> inline void read(A_t &a,B_t &b) { read(a); read(b); }
    template<typename A_t,typename B_t,typename C_t> inline void read(A_t &a,B_t &b,C_t &c) { read(a); read(b); read(c); }
    template<typename A_t,typename B_t,typename C_t,typename D_t> inline void read(A_t &a,B_t &b,C_t &c,D_t &d) { read(a); read(b); read(c); read(d); }
    template<typename A_t,typename B_t> inline void write(A_t a,B_t b) { write(a); write(b); }
    template<typename A_t,typename B_t,typename C_t> inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); }
    template<typename A_t,typename B_t,typename C_t,typename D_t> inline void write(A_t a,B_t b,C_t c,D_t d) { write(a); write(b); write(c); write(d); }
    #endif
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=25005;
    const int maxm=1000005;
    const int oo=0x3f3f3f3f;
    int n,L,R;
    struct Node { int a,b,c; };
    inline bool operator<(const Node &a,const Node &b) { return a.b<b.b; }
    Node v[maxn];
    int f[maxm<<2],pl,pr,val;
    #define Lc (o<<1)
    #define Rc (o<<1|1)
    void build(int o,int L,int R)
    {
    	if(L==R) { f[o]=oo; return; }
    	int M=(L+R)>>1;
    	build(Lc,L,M); build(Rc,M+1,R);
    	f[o]=min(f[Lc],f[Rc]);
    }
    int query(int o,int L,int R)
    {
    	if(pl<=L&&R<=pr) return f[o];
    	int M=(L+R)>>1,res=oo;
    	if(pl<=M) res=min(res,query(Lc,L,M));
    	if(pr>M) res=min(res,query(Rc,M+1,R));
    	return res;
    }
    void update(int o,int L,int R)
    {
    	if(L==R) { f[o]=val; return; }
    	int M=(L+R)>>1;
    	if(pr<=M) update(Lc,L,M);
    	else update(Rc,M+1,R);
    	f[o]=min(f[Lc],f[Rc]);
    }
    int main()
    {
    	#ifdef local
    	freopen("pro.in","r",stdin);
    	#endif
    	read(n,L,R); L++; R++;
    	for(int i=1;i<=n;i++) { read(v[i].a,v[i].b,v[i].c); v[i].a++; v[i].b++; }
    	sort(v+1,v+1+n);
    	build(1,L-1,R); val=0; pl=pr=L-1; update(1,L-1,R);
    	for(int i=1;i<=n;i++)
    	{
    		pl=v[i].a-1; pr=v[i].b;
    		val=query(1,L-1,R)+v[i].c;
    		pl=pr=v[i].b;
    		if(query(1,L-1,R)>val) update(1,L-1,R);
    	}
    	pl=pr=R;
    	val=query(1,L-1,R);
    	write(val!=oo?val:-1,'
    ');
    	return 0;
    }
    
  • 相关阅读:
    Java.io.outputstream.PrintStream:打印流
    Codeforces 732F. Tourist Reform (Tarjan缩点)
    退役了
    POJ 3281 Dining (最大流)
    Light oj 1233
    Light oj 1125
    HDU 5521 Meeting (最短路)
    Light oj 1095
    Light oj 1044
    HDU 3549 Flow Problem (dinic模版 && isap模版)
  • 原文地址:https://www.cnblogs.com/happyZYM/p/11392590.html
Copyright © 2020-2023  润新知