[ 校内OJ ] NOIP2019模拟赛(九)

第一题

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e3+5;
 4 int n;
 5 double v,u,ans,c[N],d[N];
 6 
 7 int main() {
 8     scanf("%d%lf%lf",&n,&v,&u);
 9     for(int i=1;i<=n;i++) scanf("%lf",&c[i]);
10     for(int i=1;i<=n;i++) scanf("%lf",&d[i]);
11     for(int i=1;i<=n;i++)
12      for(int j=1;j<=n;j++)
13       ans+=u/(c[j]-(i-1)*d[j]-v);
14     printf("%.3lf",ans);
15 }

第二题

设$f[i][j]$表示第$i$个景点在第$j$个时间点的被访问概率。按时间顺序依次推出各个$f[i][j]$,最后统计答案即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=105,T=485,M=3e3+5;
 4 int n,m,k,c[N],h1[N],h2[N];
 5 int cnt,fro[N],nxt[M],to[M],w[M];
 6 double ans1,ans2,b[N][T];
 7 inline int read() {
 8     int x=0; char c=getchar();
 9     while(c<'0'||c>'9') c=getchar();
10     while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
11     return x;
12 }
13 void add(int x,int y,int z) {
14     nxt[++cnt]=fro[x],to[cnt]=y,w[cnt]=z; fro[x]=cnt;
15 }
16 
17 int main() {
18     n=read(),m=read(),k=read();
19     for(int i=1;i<=n;i++) {
20         c[i]=read(); h1[i]=read(),h2[i]=read();
21     }
22     for(int i=1;i<=m;i++) {
23         int x=read(),y=read(),t=read();
24         add(x,y,t); add(y,x,t);
25     }
26     for(int i=1;i<=n;i++) b[i][c[i]]=(double)1/n;
27     for(int ti=1;ti<=k;ti++) 
28      for(int i=1;i<=n;i++) {
29          if(b[i][ti]==0) continue;
30          int tot=0;
31          for(int j=fro[i];j;j=nxt[j]) 
32           if(ti+w[j]+c[to[j]]<=k) tot++;
33          if(tot==0) continue;
34          for(int j=fro[i];j;j=nxt[j])
35           if(ti+w[j]+c[to[j]]<=k) 
36            b[to[j]][ti+w[j]+c[to[j]]]+=(double)b[i][ti]/tot;
37      }
38     for(int ti=1;ti<=k;ti++)
39      for(int i=1;i<=n;i++) 
40       ans1+=(double)b[i][ti]*h1[i],ans2+=(double)b[i][ti]*h2[i];
41     printf("%.5lf %.5lf",ans1,ans2);
42 }

第三题(弱弱地说一下这是我第一次用状压DP)

状压DP——0表示没开始任务,1表示正在任务,2表示已完成任务

因为多个任务可以同时进行,所以$s_{i}$到$t_{i}$间可能有中转点,DP时需枚举。

状态1只能由状态0转移,状态2只能由状态1转移~

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=25,M=15,INF=0x3f3f3f3f;
 4 int n,m,q,ans,a[N][N],s[M],t[M],l[M],r[M],p[M],f[60000][N];
 5 inline int read() {
 6     int x=0; char c=getchar();
 7     while(c<'0'||c>'9') c=getchar();
 8     while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
 9     return x;
10 }
11 
12 int count(int x) {
13     int tot=0;
14     for(int o=1;o<=q;o++)
15      if(x%p[o]/p[o-1]==2) tot++;
16     return tot;
17 }
18 
19 int main() {
20     n=read(),m=read(),q=read();
21     memset(a,0x3f,sizeof(a));
22     for(int i=1;i<=n;i++) a[i][i]=0;
23     for(int i=1;i<=m;i++) {
24         int x=read(),y=read();
25         a[x][y]=min(a[x][y],read());
26     }
27     for(int k=1;k<=n;k++)
28      for(int i=1;i<=n;i++)
29       for(int j=1;j<=n;j++)
30        a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
31     p[0]=1;
32     for(int i=1;i<=q;i++) {
33         s[i]=read(),t[i]=read(),l[i]=read(),r[i]=read();
34         p[i]=p[i-1]*3;
35     }
36     memset(f,0x3f,sizeof(f)); f[0][1]=0;
37     for(int i=1;i<p[q];i++)
38      for(int j=1;j<=n;j++)
39       for(int k=1;k<=q;k++) {
40           int h=i%p[k]/p[k-1];
41           if(h==1&&f[i-p[k-1]][j]+a[j][s[k]]<=r[k])
42            f[i][s[k]]=min(f[i][s[k]],max(f[i-p[k-1]][j]+a[j][s[k]],l[k]));
43           if(h==2&&f[i-p[k-1]][j]+a[j][t[k]]<=r[k])
44            f[i][t[k]]=min(f[i][t[k]],f[i-p[k-1]][j]+a[j][t[k]]);
45       }
46     for(int i=0;i<p[q];i++)
47      for(int j=1;j<=n;j++)
48       if(f[i][j]!=INF) ans=max(ans,count(i));
49     printf("%d",ans);
50 }

猜你喜欢

转载自www.cnblogs.com/qq8260573/p/10952454.html