1. 程式人生 > >2013-2014 Summer Petrozavodsk Camp, Andrew Stankevich Contest 44 (ASC 44)

2013-2014 Summer Petrozavodsk Camp, Andrew Stankevich Contest 44 (ASC 44)

暑訓最後一場組隊訓練賽,特麼故意的,把別人的WF練習題給我們寫,寫了半天才簽到兩題。靠!

B - Braess's Paradox

 Gym - 100518B 

題意:有幾個點,每個點到下一個點之間有兩條路。上面一條路的通過時間是 A*K1+B,下面一條通過時間是C*K2+D,要兩條路通過的時間數儘量相同,K1+K2=1(K1,K2是經過的人流量佔總人數的比例)。然後中間的點可以建驛站,如果中間的點不建驛站,就相當於直接從起點到終點,只有兩條路,如果建了驛站,就相當於從起點到驛站,再從驛站到終點。

題解:前兩個直接算出來就行,一個驛站都不建,就相當於兩條路,把所有點上面那條路,ai.bi,加起來就是上面那一條路的A,B,同理,下面一條路就是所有的,ci,di加起來。每個都建就是相當於一個個點走過去,暴力啊,一個點到另一個點的時間,然後全加起來就行了。後面兩個就是求最小通過時間的和最大通過時間,看似很難,其實就是一個很簡單的DP,N^2的複雜度不會超時。首先預處理從起點到當前點的A,B,C,D。然後每個點的時間就是從前面某一個點建驛站的最小值,最大值轉移過來。直接過來上面路的A,B就用兩個字首相減。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,int> P;

#define bug printf("*********\n");
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define mid (l+r)/2
#define chl 2*k+1
#define chr 2*k+2
#define lson l,mid,chl
#define rson mid,r,chr
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a));

const long long mod=1e9+7;
const int maxn=5e3+5;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
int n;
int a[maxn],b[maxn],c[maxn],d[maxn];
double qza[maxn],qzb[maxn],qzc[maxn],qzd[maxn];
double dp1[maxn],dp2[maxn];
double ans1,ans2,ans3,ans4;
int main() {
    freopen("braess.in","r",stdin);
    freopen("braess.out","w",stdout);
    scanf("%d",&n);
    for(int i=1; i<=n; i++) {
        scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
    }
    double A=0,B=0,C=0,D=0;
    for(int i=1; i<=n; i++) {       //第一種結果都不建,A相當於所有點之間的a[i]相加
        A+=a[i];
        B+=b[i];
        C+=c[i];
        D+=d[i];
    }
    double k;
    if(A+C!=0) {                    
        k=min(1.0,(D+C-B)/(A+C));//k1最大值不能超過1 
        ans1=k*A+B;
        if(k<=0) {              //k1最小值不能小於0,如果小於等於0說明所有人都走下面一條路
            ans1=C+D;
        }
    } else {
        ans1=min(B,D);          //如果AC都等於零,那就直接判斷B,D大小
    }
    ans2=0;
    for(int i=1; i<=n; i++) {
        A=a[i];                 //所有的點一個個算
        B=b[i];
        C=c[i];
        D=d[i];
        double temp;
        if(A+C!=0) {
            k=min(1.0,(D+C-B)/(A+C));
            temp=k*A+B;
            if(k<=0) {
                temp=C+D;
            }
        } else {
            temp=min(B,D);
        }
        ans2+=temp;
    }
    for(int i=1; i<=n; i++) {           //求字首
            qza[i]=qza[i-1]+a[i];
            qzb[i]=qzb[i-1]+b[i];       
            qzc[i]=qzc[i-1]+c[i];
            qzd[i]=qzd[i-1]+d[i];
        dp1[i]=inf;
    }
    dp1[0]=0;
    for(int i=1; i<=n; i++) {
        for(int j=0; j<i; j++) {
            A=qza[i]-qza[j];
            B=qzb[i]-qzb[j];            //ABCD等於上一個狀態和當前狀態的差值,
            C=qzc[i]-qzc[j];
            D=qzd[i]-qzd[j];
            double temp;
            if(A+C!=0) {
                k=min(1.0,(D+C-B)/(A+C));
                temp=k*A+B;
                if(k<=0) {
                    temp=C+D;
                }
            } else {
                temp=min(B,D);
            }
            dp1[i]=min(dp1[i],dp1[j]+temp);     //dp1保留最小值,從j驛站轉移到i驛站的最小值
            dp2[i]=max(dp2[i],dp2[j]+temp);     //最大值
        }
    }
    ans3=dp1[n];
    ans4=dp2[n];
    printf("%.10f\n%.10f\n%.10f\n%.10f\n",ans1,ans2,ans3,ans4);

    return 0;
}

I - Intelligent Tourist

 Gym - 100518I 

題意:有N場考試,第i考試需要複習pi天,考試時間是di,考試的時間沒法複習,如果沒有複習多天那場考試就不會去,就會去複習其他考試,中間有些天有活動,活動時間是s-t活動時間不會去複習,問最多能通過機場考試。

題解:貪心,這題賊他媽傻逼,漏看了一個條件,DEBUG一個小時。。。,從後面往前面掃,每次選需要複習時間最少的一場考試,因為這個時間只能給後面的所以不用擔心選的考試時間已經過了,至於考試時間不能複習,你直接把考試也當作複習的時間,不去考試就相當於少複習這種科目一天,去了就相當於多複習一天。。。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,int> P;

#define bug printf("*********\n");
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define mid (l+r)/2
#define chl 2*k+1
#define chr 2*k+2
#define lson l,mid,chl
#define rson mid,r,chr
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a));

const long long mod=1e9+7;
const int maxn=1e5+5;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
int n,m;
struct one {
    ll d,p;
    int id;
    bool operator<(const one a)const {
        return d<a.d;
    }
} X;
struct two {
    ll st,en;
    bool operator<(const two a)const {
        return st<a.st;
    }
} H;
priority_queue<one> q1;
priority_queue<two> q2;
priority_queue<P,vector<P>,greater<P> >q;

int main() {
    freopen("intelligent.in","r",stdin);
    freopen("intelligent.out","w",stdout);
    while(~scanf("%d",&n)&&n) {
        vector<int> v;
        for(int i=0; i<n; i++) {
            scanf("%I64d%I64d",&X.d,&X.p);
            X.p++;
            X.id=i+1;
            q1.push(X);
        }
        scanf("%d",&m);
        for(int i=0; i<m; i++) {
            scanf("%I64d%I64d",&H.st,&H.en);
            q2.push(H);
        }

        while(q2.size()) {
            if(q2.top().st>q1.top().d) {
                q2.pop();
            } else break;
        }
        while(q1.size()) {
            X=q1.top();
            q1.pop();
            ll temp;
            if(q1.size()==0)temp=0;
            else temp=q1.top().d;
            ll tim=0;
            tim=X.d-temp;
            while(q2.size()) {
                H=q2.top();
                if(H.st>temp) {
                    q2.pop();
                    tim-=H.en-H.st+1;
                } else break;
            }

            if(X.p==0) {
                v.push_back(X.id);
            } else q.push(P(X.p,X.id));

            while(tim>0&&q.size()) {
                P temp2=q.top();
                q.pop();
                if(tim>=temp2.first) {
                    tim-=temp2.first;
                    v.push_back(temp2.second);
                } else {
                    temp2.first-=tim;
                    tim=0;
                    q.push(temp2);
                }
            }
        }
        while(q1.size())q1.pop();
        while(q2.size())q2.pop();
        while(q.size())q.pop();
        sort(v.begin(),v.end());
        int ans=v.size();
        printf("%d\n",ans);
        for(int i=0; i<ans; i++) {
            printf("%d",v[i]);
            if(ans==i+1)printf("\n");
            else printf(" ");
        }
        if(ans==0)puts("");
    }
    return 0;
}