[Passenger count garlic] [ore acquisition search in mind, Tarjan desired condensing point + Dp]

Judge Online : Total passenger garlic informatics simulation game set to improve in March

The Label : record search, TarJan shrink point, Fenwick tree, expect Dp

answer

The whole subject a combination of two unrelated issues as:

part1

Question: For each starting and ending points of inquiry to determine the starting point to the end of the maximum value of the ore can be harvested.

Ideas:

1. ore narrow range, and only when the value of the harvest and whether it has , but not with the number of collection has nothing to do, you can use the compressed state indicates the status of the current collecting ore;

2. Since it is unidirectional sides and may form a ring, with \ (Tarjan \) condensing point, and then transferred. Or direct memory of DFS / BFS , with \ (dp [i] [j ] [sta] \) represents from \ (I \) to \ (J \) , whether it is possible to collect status \ (STA \) ore. Finally, the maximum you can find it again.

part2

Question: arrangements which entrust execution so expect a profit maximum.

Ideas:

1. organize information entrusted to:

For a commission \ ((yi, Si, Ti, PI, CI, li) \) , we can \ ((si, ti) \ ) to calculate the benefits of this commission as well as a pretreatment portion ( No minus costs) \ (the Wi \) ; start time and end time of this commission \ ((yi, yi + li) \) , here abbreviated as \ ((L, r) \) . We expressed a request using a structure { \ (L, R & lt, W, C, P \) }.

2. Determine the transfer order

There is no doubt based on the first start time \ (li \) all commissioned sorted.

The definition of state \ (dp [i] \) , said it had considered the \ (i..q \) commissioned and accepted a commission \ (i \) at the maximum expected profit . Then only the reverse transfer can be. For the current commission \ (i \) , we use binary search on (O (logq) \) \ in time, find the first starting time is greater than equal to the current end time of the commission entrusted \ (J \) . Then transferred equation is: \ (DP [I] = max (DP [J ... Q] + W_i) * (. 1-P_i) -c_i \) , this explanation is not well understood, and the interval \ ([ j, q] \) is the maximum value of the array may be in a tree / tree line maintenance.

This title is over, the main difficulty is the subject of more variable, as long as clarify the relationship into two problem-solving just fine.

part1 practice more, but because of the small data range are feasible. part2 time complexity is \ (O (NlogN) \) .

#include<bits/stdc++.h>
using namespace std;
const int N=110,M=210,Q=1e5+10;
int val[1030];
int n,m,k,q,has[N];

struct edge{int to,nxt;}e[M];
int head[N],cnt;
inline void link(int u,int v){
    e[++cnt].to=v;e[cnt].nxt=head[u];
    head[u]=cnt;
}

bool ok[N][N][1030];
void dfs(int s,int x,int sta){
    if(ok[s][x][sta])return;
    ok[s][x][sta]=1;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;dfs(s,y,sta|has[y]);
    }
} 
struct Node{
    int l,r,w,c;
    double p;
}x[Q];
inline bool cmp(Node a,Node b){return a.l<b.l;}
void pre(){
    for(register int i=1;i<=n;i++)dfs(i,i,has[i]);
    for(register int i=1,u,v;i<=q;i++){
        scanf("%d%d%d%lf%d%d",&x[i].l,&u,&v,&x[i].p,&x[i].c,&x[i].r);
        x[i].r+=x[i].l;
        for(register int o=0;o<(1<<k);o++)if(ok[u][v][o]){
            if(val[o]>x[i].w)x[i].w=val[o];
        }
    }
}
double c[Q];
inline double ask(int x){
    double res=0;
    while(x<=q){res=max(res,c[x]);x+=x&(-x);}
    return res;
}
inline void update(int x,double d){
    while(x){c[x]=max(c[x],d);x-=x&(-x);}
}
inline void Dp(){
    sort(x+1,x+q+1,cmp);
    for(register int i=q;i>=1;i--){ 
        //如果接受i委托,下一个最早能进行的委托是id 
        int l=i+1,r=q,id=q+1;
        while(l<=r){
            int mid=l+r>>1;
            if(x[i].r<=x[mid].l)r=mid-1,id=mid;
            else l=mid+1;
        }
        double now=(ask(id)+x[i].w)*(1.0-x[i].p)-x[i].c;
        update(i,now);
    }
    printf("%.6f\n",ask(1));
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&q);
    for(register int i=1;i<=n;i++){
        char s[12];scanf("%s",s);
        for(int j=0;j<strlen(s);j++)if(s[j]=='1')has[i]|=1<<j;
    }
    for(register int i=1;i<=m;i++){
        int u,v;scanf("%d%d",&u,&v);
        link(u,v);
    }
    for(register int i=0,w;i<k;i++){
        scanf("%d",&w);
        for(int j=0;j<(1<<k);j++)if((1<<i)&j)val[j]+=w;
    }
    pre();  
    Dp();
}

Guess you like

Origin www.cnblogs.com/Tieechal/p/11487153.html