bzoj1571【DAG上dp】

来源:互联网 发布:方块乐器软件 编辑:程序博客网 时间:2024/04/30 07:21

首先把时间离散化,并建n*m个点(n是总的时间点数,m是技术等级数),(t,a)表示位于t好时间点并且科技等级为m,然后就变成了DAG上的最短路,dp即可

#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;#define id(a,b) (((b)-1)*post+a)typedef long long LL;inline LL read(){LL x=0;bool f=0;char c=getchar();for (;c<'0'||c>'9';c=getchar()) f=c=='-'?1:0;for (;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';return f?-x:x;}const int maxa=100,N=20010,M=5000010,oo=0x3f3f3f3f;int T,S,R,n=0,mint=oo,st,ed,stk[N],sk=0,dis[N],ll=0,to[M],next[M],head[N],wt[M],du[N],li[N],ri[N],ai[N],sum[N],pos[N],post=0;bool ok[N];struct na{int a,t;}e[N];inline bool cmp(const na &lhs,const na &rhs){return lhs.a<rhs.a;}inline void adde(int u,int v,int w){to[++ll]=v;next[ll]=head[u];head[u]=ll;wt[ll]=w;du[v]++;}inline int find(int x){if (pos[1]==x) return 1;if (pos[post]==x) return post;int l=1,r=post,mid;while (l+1<r){if (pos[mid=l+r>>1]<=x) l=mid;else r=mid;}return l;}int main(){T=read();S=read();R=read();for (int i=1;i<=S;i++){li[i]=read();ri[i]=li[i]+read();ai[i]=read();if (ri[i]<T) pos[++post]=li[i],pos[++post]=ri[i],ok[i]=1;}sort(pos+1,pos+post+1);for (int i=1;i<=S;i++)if (ok[i]) li[i]=find(li[i]),ri[i]=find(ri[i]);n=ed=maxa*post+2;st=n-1;for (int i=1;i<=S;i++)for (int j=1;j<ai[i];j++)if (ok[i]) adde(id(li[i],j),id(ri[i],ai[i]),0);for (int i=1;i<=R;i++) e[i].a=read(),e[i].t=read();sort(e+1,e+R+1,cmp);for (int a=1,k=1;a<=maxa;a++){while (k<=R&&e[k].a==a) mint=min(mint,e[k++].t);if (a==1){for (int i=1;i<=post;i++) adde(st,id(i,1),pos[i]/mint);adde(st,ed,T/mint);}for (int i=1;i<=post;i++){for (int j=i+1;j<=post;j++)adde(id(i,a),id(j,a),(pos[j]-pos[i])/mint);adde(id(i,a),ed,(T-pos[i])/mint);}}for (int i=1;i<=n-2;i++)if (!du[i]) adde(st,i,-oo);stk[sk++]=st;memset(dis,0x80,sizeof dis);dis[st]=0;while (sk){int u=stk[--sk];for (int i=head[u],v;i;i=next[i]){if (!--du[v=to[i]]) stk[sk++]=v;dis[v]=max(dis[v],dis[u]+wt[i]);}}printf("%d\n",dis[ed]);return 0;}


0 0
原创粉丝点击