Codeforces Round #105 (Div. 2)

来源:互联网 发布:c指针编程之道 编辑:程序博客网 时间:2024/04/29 22:22

比赛地址:http://codeforces.com/contest/148

A:暴力题,比赛的时候脑残地打错一个变量,还以为自己看错题目,纠结很久才出来。

 

B:模拟一下就行了,注意精度。

 

C:构造数列。

可以这样来构造,尽量满足最小。

1 2 4 8 16 17 18 19 20 20 20 20 20 20    (4个wow,4个oh)

先满足wow,再满足oh,注意n为1和b为0的情况。

 

D:概率DP,用dp[i][j]表示有i个白老鼠,j个黑老鼠,princess先取的赢的概率。

那么状态转移方程为

dp[i][j]=(i/(i+j))+(j/(i+j))*((j-1)/(i+j-1))*((i/(i+j-2))*dp[i-1][j-2]+((j-2)/(i+j-2))*dp[i][j-3]);

注意初始化。j<=2 的情况。

注:(dp[i][j]=princess先取走的是白色+princess先取走的是黑色*dragon接着取走的是黑色*(逃走的是白色*dp[i-1][j-2]+逃走的是黑色*dp[i][j-3]);)

 

#include <iostream>#include <algorithm>#include <cstdio>#include <string>#include <cmath>#include <vector>using namespace std;double dp[1005][1005];int main(){    int w,b;while(scanf("%d %d",&w,&b)!=EOF){      if(w==0)   {      printf("0.000000000\n");  continue;   }   for(int i=0;i<=b;i++)   dp[0][i]=0;       for(int i=1;i<=w;i++)   dp[i][0]=1;   for(int i=1;i<=w;i++)   dp[i][1]=(double)(i)/(i+1);   for(int i=1;i<=w;i++)   dp[i][2]=(double)(i)/(i+2)+(2.0/(i+2))*(1.0/(i+1));   if(b<=2)   {   printf("%.9f\n",dp[w][b]);   continue;   }       for(int i=1;i<=w;i++)   {   for(int j=3;j<=b;j++)   {      double mw=(double)i;              double mb=(double)j;      dp[i][j]=(mw/(mw+mb))+(mb/(mw+mb))*((mb-1)/(mw+mb-1))*((mw/(mw+mb-2))*dp[i-1][j-2]+((mb-2)/(mw+mb-2))*dp[i][j-3]);   }   }   printf("%.9f\n",dp[w][b]);}return 0;}


 

E:dp,dp[i][j]表示前i行中,取j个数的最大值。

那么状态转移方程为:

dp[i][j]=max(dp[i][j],dp[i-1][j-k]+cnt[i][k]) ; (k>=0 && k<=num[i]);

cnt[i][j]表示第i行取j个数的最大值。可以预处理。

枚举j的时候,j小于前面的个数总数,缩小范围。

 

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>#include <vector>using namespace std;int n,m;const int maxn = 105;const int maxm = 10005;int num[maxn];int snum[maxn];int a[maxn][maxn];int cnt[maxn][maxn];int sum[maxn][maxn];int dp[maxn][maxm];inline int m_max(int mt1,int mt2){    if(mt1>mt2)   return mt1;   return mt2;}int main(){    while(scanf("%d %d",&n,&m)!=EOF){   snum[0]=0;       for(int i=1;i<=n;i++)   {   scanf("%d",&num[i]);   snum[i]=snum[i-1]+num[i];   sum[i][0]=0;   for(int j=1;j<=num[i];j++)   {      scanf("%d",&a[i][j]);  sum[i][j]=sum[i][j-1]+a[i][j];   }   }       memset(cnt,0,sizeof(cnt));   for(int i=1;i<=n;i++)   {   for(int j=1;j<=num[i];j++)   {      for(int k=0;k<=j;k++)                cnt[i][j]=m_max(cnt[i][j],sum[i][k]+sum[i][num[i]]-sum[i][num[i]-(j-k)]);   }   }  /* for(int i=1;i<=n;i++)   {   for(int j=0;j<=num[i];j++)   printf("%d ",cnt[i][j]);   printf("\n");   }*/       memset(dp,0,sizeof(dp));       for(int i=0;i<=num[1];i++)   dp[1][i]=cnt[1][i];   for(int i=2;i<=n;i++)   {          for(int j=0;j<=snum[i];j++)  {     for(int k=0;k<=num[i] && k<=j ;k++)  dp[i][j]=m_max(dp[i][j],cnt[i][k]+dp[i-1][j-k]);  }     }   printf("%d\n",dp[n][m]);}return 0;}



 

 

原创粉丝点击