2014 Multi-University Training Contest 1

A hdu4861

打表找规律 

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<cmath>
 7 using namespace std;
 8 #define eps 1e-4
 9 #define zero(x) ((fabs(x)<eps)?0:x)
10 int main()
11 {
12     int n,k;
13     while(~scanf("%d%d",&n,&k))
14     {
15         int x=n/(k-1);
16         if(x%2==0)cout<<"NO"<<endl;
17         else cout<<"YES"<<endl;
18     }
19     return 0;
20 }
View Code

 

hdu4862

D hdu4864

 把机器和任务放在一块以时间排序,因为2*100《500 时间的影响远远大于等级 

优先顺序依次为:时间由大到小,等级由大到小,先机器后任务

然后遍历开数组存以yi为等级的机器还有多少个,当遍历到任务时从当前任务的等级y--100 寻找可用的机器

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 101010
12 #define LL __int64
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 struct node
18 {
19     int x,y;
20     int flag;
21 }p[N*2];
22 int o[110];
23 bool cmp(node a,node b)
24 {
25     if(a.x==b.x)
26     {
27         if(a.y==b.y)
28         return a.flag<b.flag;
29         return a.y>b.y;
30     }
31     return a.x>b.x;
32 }
33 int main()
34 {
35     int n,m,i,j;
36     int t = 0;
37     while(scanf("%d%d",&n,&m)!=EOF)
38     {
39 //        t++;
40 //        if(t>7)
41 //        {
42 //            while(1);
43 //        }
44         memset(o,0,sizeof(o));
45         for(i = 1; i <= n ;i++)
46         {
47             scanf("%d%d",&p[i].x,&p[i].y);
48             p[i].flag = 1;
49         }
50         for(i = 1+n; i<= n+m ; i++)
51         {
52             scanf("%d%d",&p[i].x,&p[i].y);
53             p[i].flag = 2;
54         }
55         sort(p+1,p+m+n+1,cmp);
56         int ans = 0;
57         LL sum = 0;
58         for(i = 1; i <= n+m; i++)
59         {
60             //cout<<p[i].x<<" "<<p[i].y<<" "<<p[i].flag<<endl;
61             if(p[i].flag==1)
62             {
63                 o[p[i].y]++;
64             }
65             else
66             {
67                 for(j = p[i].y ; j<=100 ; j++)
68                 {
69                     if(!o[j]) continue;
70                     o[j]--;
71                     ans++;
72                     sum+=500LL*p[i].x+2*p[i].y;
73                     break;
74                 }
75             }
76         }
77         printf("%d %I64d\n",ans,sum);
78     }
79     return 0;
80 }
View Code

 

E

 求以给出干燥程度序列的最大概率所得的路径,首先求这样一个序列的最大概率,然后记录路径。

dp[i][j][k]表示第i天干燥程度为j天气为k dp[i][j][k] = max(dp[i][j][k],dp[i-1][c[i-1]][g]*a[g][j]*b[j][k])  c[i]表示第i天的干燥程度 ab表示题目给出的两个概率矩阵

因为数值太小,用log转乘法为加法

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100000
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 double dp[55][5][5];
 18 double o[5];
 19 int ps[55][5][5];
 20 int c[55];
 21 int ans[55];
 22 double pa[4][4] = {0,0,0,0,0,0.5,0.375,0.125,0,0.25,0.125,0.625,0,0.25,0.375,0.375};
 23 double pb[4][5] = {0,0,0,0,0,0,0.6,0.2,0.15,0.05,0,0.25,0.3,0.2,0.25,0,0.05,0.1,0.35,0.5};
 24 int judge(char *s)
 25 {
 26     if(strcmp(s,"Dry")==0) return 1;
 27     else if(strcmp(s,"Dryish")==0) return 2;
 28     else if(strcmp(s,"Damp")==0) return 3;
 29     return 4;
 30 
 31 }
 32 int main()
 33 {
 34     char s[10];
 35     int t,i,j,n;
 36     int kk =0 ;
 37     cin>>t;
 38     while(t--)
 39     {
 40         cin>>n;
 41         for(i = 1; i <= n ; i++)
 42             for(j = 1 ;j <= 4; j++)
 43                 for(int g = 1; g <= 3;  g++)
 44                 dp[i][j][g] = -INF;
 45         o[1] = 0.63;
 46         o[2] = 0.17;
 47         o[3] = 0.2;
 48         for(i = 1; i <= n; i++)
 49         {
 50             scanf("%s",s);
 51             int k = judge(s);
 52             c[i] = k;
 53         }
 54         for(i = 1; i <= 3 ; i++)
 55         {
 56             dp[1][c[1]][i] = log(o[i])+log(pb[i][c[1]]);
 57         }
 58         for(i = 2; i <=n ; i++)
 59         {
 60             int k = c[i];
 61             for(j = 1; j <= 3 ;j++)
 62             {
 63                 for(int g = 1; g <= 3 ; g++)
 64                 {
 65                     double s = log(pa[g][j]);
 66                     double ts = dp[i-1][c[i-1]][g]+s+log(pb[j][k]);
 67                     if(dp[i][k][j]<ts)
 68                     {
 69                         dp[i][k][j] = ts;
 70                         ps[i][k][j] = g;
 71                     }
 72                 }
 73             }
 74         }
 75         int x;
 76         double maxz = -INF;
 77         for(i = 1; i <= 3 ; i++)
 78         {
 79             if(maxz<dp[n][c[n]][i])
 80             {
 81                 maxz =dp[n][c[n]][i];
 82                 ans[n] = i;
 83                 x = ps[n][c[n]][i];
 84             }
 85         }
 86         int y = n;
 87         while(y!=1)
 88         {
 89             y--;
 90             ans[y] = x;
 91             x = ps[y][c[y]][x];
 92         }
 93         printf("Case #%d:\n",++kk);
 94         for(i = 1; i <= n ; i++)
 95         {
 96             if(ans[i]==1)
 97             puts("Sunny");
 98             else if(ans[i]==2)
 99             puts("Cloudy");
100             else puts("Rainy");
101         }
102     }
103     return 0;
104 }
View Code

 

H

 官方解答:

最终的结果一定是连续出现的,只需要求出最终的区间。

因为如果对同一张牌进行两次操作,牌的状态不改变。故牌的翻转次数一定是减少偶数次。如果所有数的和是奇数,那么最终结果也一定是奇数。同理,偶数也是一样的。

所以只要递推求出最后的区间,计算sumCxim)(i=012。。。)),m是总牌数,xi是在区间内连续的奇数或偶数,在模10^9+9就是最终的答案。

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100010
12 #define LL long long
13 #define INF 0xfffffff
14 #define mod 1000000009
15 const double eps = 1e-8;
16 const double pi = acos(-1.0);
17 const double inf = ~0u>>2;
18 int x[N];
19 LL pp[N];
20 void init()
21 {
22     int i;
23     pp[0] = 1;
24     for(i = 1; i <= N-10 ; i++)
25     {
26         pp[i] = (pp[i-1]*i)%mod;
27     }
28 }
29 
30 LL fastmod(LL a,LL k)
31 {
32     LL b = 1;
33     while(k)
34     {
35         if(k&1)
36         b = a*b%mod;
37         a = (a%mod)*(a%mod)%mod;
38         k/=2;
39     }
40     return b;
41 }
42 
43 int main()
44 {
45     int n,m,i;
46     init();
47     while(scanf("%d%d",&n,&m)!=EOF)
48     {
49         for(i = 1 ;i <= n; i++)
50         scanf("%d",&x[i]);
51         int minz = 0,maxz = 0;
52         for(i = 1 ;i <= n ; i++)
53         {
54             int tmz = minz-x[i];
55             int tma = maxz+x[i];
56             if(tmz<0)
57             {
58                 if(x[i]<=maxz)
59                 tmz = abs(minz-x[i])%2;
60                 else tmz = x[i]-maxz;
61             }
62             if(tma>m)
63             {
64                 if(x[i]+minz<=m)
65                 tma = m-abs(x[i]-maxz)%2;
66                 else tma = m-(x[i]+minz-m);
67             }
68             minz = tmz;
69             maxz = tma;
70         }
71         LL ans = 0;
72         for(i = minz; i <= maxz ; i+=2)
73         {
74             ans = (ans+(pp[m]*fastmod((pp[i]*pp[m-i])%mod,mod-2))%mod)%mod;
75         }
76         cout<<ans<<endl;
77     }
78     return 0;
79 }
View Code

 

I

因为只有+50和-100,可以把1000压缩成20,容易列出dp方程i<=j时 dp[i][j] = p*dp[i+1][j]+(1-p)*dp[min(i-2,0)][j]+1;

循环一遍列出多个这样的方程,用高斯消元求解,这里需要精度高一些。

 

 1 #include <iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<cmath>
 7 using namespace std;
 8 #define eps 1e-15
 9 #define zn 403
10 double a[500][500];
11 double ans[455];
12 int o[510][510];
13 void gauss(int zw,int zr)
14 {
15     int i,j,k,g = 0;
16     for(k = 0 ; k < zw && g < zr; k++,g++)
17     {
18         i = k;
19         for(j = k+1 ; j <= zw ; j++)
20         {
21             if(fabs(a[j][g])>fabs(a[i][g]))
22             i = j;
23         }
24         if(fabs(a[i][g])<eps)
25         {
26             continue;
27         }
28         if(i!=k)
29         for(j = k ;j <= zr ; j++)
30         swap(a[i][j],a[k][j]);
31         for(i = k+1 ; i <= zw ; i++)
32         {
33             if(fabs(a[i][k])<eps) continue;
34             double s = a[i][g]/a[k][g];
35             a[i][g] = 0.0;
36             for(j = g+1 ; j <= zr; j++)
37                 a[i][j] -= s*a[k][j];
38         }
39     }
40     for(i = zw ; i >= 0 ; i--)
41     {
42         if(fabs(a[i][i])<eps) continue;
43         double s = a[i][zn];
44         for(j = i+1 ; j <= zw ;j++)
45         s-=a[i][j]*ans[j];
46         ans[i] = s/a[i][i];
47     }
48 }
49 int main()
50 {
51     int i,j;
52     double p;
53     while(scanf("%lf",&p)!=EOF)
54     {
55         memset(a,0,sizeof(a));
56         memset(ans,0,sizeof(ans));
57         int g = 0;
58         int e = 0;
59         for(i = 0 ; i < 20 ; i++)
60             for(j = 0; j < 20 ; j++)
61             o[i][j] = ++e;
62         o[19][20] = ++e;
63         o[20][19] = ++e;
64         for(i = 0; i < 20 ; i++)
65             for(j = 0; j < 20 ; j++)
66             {
67                 ++g;
68                 if(i>j)
69                 {
70                     a[g][o[i][j]]  += 1.0;
71                     int tj = max((j-2),0);
72                     a[g][o[i][tj]] += (p-1.0);
73                     tj = min(j+1,20);
74                     a[g][o[i][tj]]-=p;
75                 }
76                 else
77                 {
78                     a[g][o[i][j]]  += 1.0;
79                     int ti = max((i-2),0);
80                     a[g][o[ti][j]] += (p-1.0);
81                     ti = min(i+1,20);
82                     a[g][o[ti][j]]-=p;
83                 }
84             }
85         for(i = 1; i <= g ; i++)
86         a[i][e+1] = 1;
87         gauss(g,e+1);
88        // for(i = 1; i <= 441 ; i++)
89         printf("%f\n",ans[1]);
90     }
91     return 0;
92 }
View Code
posted @ 2014-07-23 17:12  _雨  阅读(146)  评论(0编辑  收藏  举报