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 }
B 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 ",ans,sum); 78 } 79 return 0; 80 }
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: ",++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 }
H
官方解答:
最终的结果一定是连续出现的,只需要求出最终的区间。
因为如果对同一张牌进行两次操作,牌的状态不改变。故牌的翻转次数一定是减少偶数次。如果所有数的和是奇数,那么最终结果也一定是奇数。同理,偶数也是一样的。
所以只要递推求出最后的区间,计算sum(C(xi,m)(i=0,1,2。。。)),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 }
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 ",ans[1]); 90 } 91 return 0; 92 }