Codeforces Round #105 (Div. 2)

來源:互聯網
上載者:User

AB水題。

C貪心構造。

分情況討論:

1、a == 0或b != 0 ,先處理b個的情況,可以利用2的冪次來構造,因為例如1,2,4,8,16......2的冪次序列滿足後一個總大於前面所有值之和,可以化成二進位驗證,在處理a

2、a != 0&& b==0,如果a==n-1&&b==0很明顯矛盾;否則就先處理a,再處理b,前面要有兩個1保證a情況

int main(){    int n,a,b;    while(scanf("%d%d%d",&n,&a,&b) != -1){        int i,j;        if(b!=0 || a==0){            int x = 1;            printf("%d",x);            for(i=0;i<b;i++){                x*=2;                printf(" %d",x);            }            for(i=0;i<a;i++){                x++;                printf(" %d",x);            }            for(i=0;i<n-a-b-1;i++){                printf(" %d",x);            }        } else {//b==0 && a!=0            if(a==n-1){                puts("-1");            } else {                int x = 1;                printf("%d",x);                printf(" %d",x);                for(i=0;i<a;i++){                    x++;                    printf(" %d",x);                }                for(i=0;i<n-a-2;i++){                    printf(" %d",x);                }            }        }        puts("");    }    return 0;}

D機率dp

#define N 1001double dp[N][N][3];//0—princess win,1—dragon not win,2—jumpbool vis[N][N][3];double dfs(int w,int b,int k){    double ret = 0.0;    if(w <= 0 && b <= 0)return 0.0;    if(vis[w][b][k])return dp[w][b][k];    vis[w][b][k] = 1;    if(k == 0){//princess win        if(w)ret += 1.0*w/(w+b);        if(b)ret += dfs(w,b-1,1)*1.0*b/(w+b);    } else if(k == 1){//dragon not win        if(w)ret += 0.0*w/(w+b);        if(b)ret += dfs(w,b-1,2)*1.0*b/(w+b);    } else if(k == 2){//jump        if(w)ret += dfs(w-1,b,0)*1.0*w/(w+b);        if(b)ret += dfs(w,b-1,0)*1.0*b/(w+b);    }    return dp[w][b][k] = ret;}int main(){    int w,b;    while(scanf("%d%d",&w,&b) != -1){        memset(vis,0,sizeof(vis));        printf("%.10f\n",dfs(w,b,0));    }    return 0;}

E裸dp。

題意是說有n層書架,每層放有k個值,問拿出m個值最大是多少,拿的時候要求是每層只能從兩邊一直往裡面拿出。

方法:做兩次dp,第一次將每行dp,設f[i][j]表示第i行取j個最大值,j<=m,轉移方程f[i][j] = max(f[i][j],suml[s] + sumr[t]){s+t=j};第二次對前i行做dp,設dp[i][j]表示前i行取j個最大值,j<=m,轉移方程dp[i][j] = max(dp[i][j],dp[i-1][j-k]+f[i][k])

最後dp[n][m]就是結果。

int a[101][101];int f[101][10001];//第i行取j個最大值,j<=mint dp[101][10001];//前i行取j個最大值,j<=mint suml[101];int sumr[101];int n,m;void dp1(int r){    int i,j;    int cnt = a[r][0];    suml[0] = 0;    for(i=1;i<=cnt;i++){        suml[i] = a[r][i];        suml[i] += suml[i-1];    }    sumr[0] = 0;    for(i=cnt;i>=1;i--){        sumr[cnt-i+1] = a[r][i];        sumr[cnt-i+1] += sumr[cnt-i];    }    for(i=0;i<=cnt;i++){        if(i>m)break;        for(j=0;j<i;j++){            int ll = j;            int rr = i-j;            f[r][i] = max(f[r][i],suml[ll] + sumr[rr]);            f[r][i] = max(f[r][i],suml[rr] + sumr[ll]);        }    }}void dp2(){    int i,j,k;    for(i=1;i<=n;i++){        for(j=0;j<=m;j++){            for(k=0;k<=min(j,a[i][0]);k++){                dp[i][j] = max(dp[i][j],dp[i-1][j-k]+f[i][k]);            }        }    }    printf("%d\n",dp[n][m]);}int main(){    while(scanf("%d%d",&n,&m) != -1){        int i,j,k;        memset(f,0,sizeof(f));        memset(dp,0,sizeof(dp));        for(i=1;i<=n;i++){            scanf("%d",&a[i][0]);            for(j=1;j<=a[i][0];j++){                scanf("%d",&a[i][j]);            }            dp1(i);        }        dp2();    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.