首页 > 其他 > 详细

第n+1次考试

时间:2017-10-09 21:36:03      阅读:353      评论:0      收藏:0      [点我收藏+]

题目:

1. 中位数

【问题描述】

给定C个不同物品,每个物品有一重量和体积,保证每个物品的重量不一样。从中选出N个物品,在体积不超过F的情况下,使得选出的物品的重量的中位数最大。所谓中位数,就是排序后处在最中间的重量,比如3,8,9,7,5的中位数是7

【输入格式】

第一行:三个用空格分开的整数:NCF≤ ≤ 19999≤ ≤ 105

≤ ≤ × 109

第二行到C + 1行:每行有两个用空格分开的整数。第一个数是这个物品的重量Wi,第二个数是这个物品的体积Qi

【输出格式】

第一行:一个整数,表示可以得到的最大中位数,如果F装不下任何N个物品,则输出-1

【输入样例】

3 5 70

30 25

50 21

20 20

5 18

35 30

【输出样例】

35

【样例解释】

选择重量为 5, 35, 50 的物品,中位数为 35,体积18 + 30 + 21 = 69,小于70

【数据范围】

    40%的数据,≤ N≤ 200

100%的数据,≤ ≤ 19999≤ ≤ 105≤ ≤ × 109≤ Qi≤ 105≤ Wi≤ × 109。保证n为奇数。

 

 

2. 爆炸

【问题描述】

 有N个城市,M条双向道路组成的地图,城市标号为1到N。“西瓜炸弹”放在1号城市,保证城市1至少连接着一个其他城市。“西瓜炸弹”有P/Q的概率会爆炸,每次进入其它城市时,爆炸的概率相同。如果它没有爆炸,它会随机的选择一条道路到另一个城市去,对于当前城市所连接的每一条道路都有相同的可能性被选中。对于给定的地图,求每个城市“西瓜炸弹”爆炸的概率。

例如,假设只有两个城市1和2,它们被一条道路连接起来。最开始“西瓜炸弹”放在城市1,每次进入城市它都有1/2的可能性爆炸: 

1 — 2

我们就有以下可能的路径(其中最后一项是结束城市,即“西瓜炸弹”爆炸并污染该城市): 

1: 1 
2: 1-2 
3: 1-2-1 
4: 1-2-1-2 
5: 1-2-1-2-1 
etc. 

为了找出“西瓜炸弹”在城市1爆炸的可能性,我们可以把第1、3、5…种路径出现的概率加起来(在这个例子中即把所有奇数路径出现的可能性加起来)。 
对于第k种路径出现的可能性为(1/2)^k:在经过前k-1次时,炸弹绝对不会在城市1爆炸(每一次的概率为1 – 1/2 = 1/2),然后最后在城市1爆炸(概率为1/2)。 

因此,在城市1爆炸的可能性就是 1/2 + (1/2)^3 + (1/2)^5 + … ,把这些数都加起来就等于2 / 3,约为0.666666667。 
所以在城市2爆炸的可能性就是1/3,约为0.333333333。

【输入格式】

第1行:四个被空格分隔整数:N,M,P和Q 

第2..M+1行:第i行描述了两个空格分隔的整数:A_j 和 B_j(表示城市A_j与B_j相连)

【输出格式】

第1..N行:第i行为一个小数,表示第i个城市 “西瓜炸弹”爆炸的概率。至少要精确到10^-6才有效。

【输入样例1】

2 1 1 2 
1 2

【输出样例1】

0.666666667 
0.333333333

【输入样例2】

3 2 1 3

1 2

3 2

【输出样例2】

0.466666667

0.400000000

0.133333333

【数据范围】

20%  2<=N<=25 , 1<=M<=100

100% 2 <= N <= 300 ,1 <= M <= 44850 ,1 <= P <= 1,000,000,1 <= Q <= 1,000,000

 

3.序列划分

 

【题目描述】

给定一个序列{An},现在,需要把这个序列划分成K个子序列,使得每个子序列包含的数的个数不少于2,并且要么非升,要么非降。你的任务就是求出K的最小值。

 

【输入文件】

输入第一行一个正整数N,表示序列长度,接下来N行,第i行表示元素Ai-1

 

【输出文件】

如果不能划分这个序列,输出一个数0;否则输出K

 

【样例输入1

6

12

33

97

18

15

33

 

【样例输出1

2

【样例输入2

1

88

【样例输出2

0

【样例输入3

4

77

22

22

11

【样例输出3

1

【数据规模】

对于30%的数据,1<=N<=10

对于100%的数据,1<=N<=251<=Ai<=100

 

 题解:

一:按照体积排序

1.预处理前i小、大的体积的物品的重量拿n/2个的最小重量

然后一个个枚举过去,看看是否成立

至于预处理就用一个堆好了

二:高斯消元+概率dp

本来想要简单的dp+收敛,没有想到数据那么坑。。。

(其实按照随机的概率大概可以过p/q>0.02的情况吧)

正解:高斯校园+概率

列出n个方程,解n个数字,就是高斯消元

三:迭代深搜

枚举有多少个可以,然后按照类似与导弹拦截的贪心方法做贪心

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=200005;
int f[N],d[N],l,a[N],b[N],n,m,F;
long long f1[N],f2[N];
void up(int x)
{
    if (x==1)return;
    if (d[x]>d[x/2])
     {
         swap(d[x],d[x/2]);
         up(x/2);
     }
}
void down(int x)
{
    int i=x;
    if (x*2<=l&&d[x]<d[x*2])i=x*2;
    if (x*2<l&&d[i]<d[x*2+1])i=x*2+1;
    if (i!=x)
     {
         swap(d[x],d[i]);
         down(i);
     }
}
int cmp(int x,int y)
{
    return a[x]<a[y];
}
int main()
{
    freopen("finance.in","r",stdin);
    freopen("finance.out","w",stdout); 
    scanf("%d%d%d",&n,&m,&F);
    for (int i=1;i<=m;i++)scanf("%d%d",&a[i],&b[i]),f[i]=i;
    sort(f+1,f+m+1,cmp);
    for (int i=1;i<=n/2;i++)d[i]=b[f[i]],f1[i]=f1[i-1]+b[f[i]];
    l=n/2;
    for (int i=1;i<=n/2;i++)up(i);
    for (int i=n/2+1;i<=m;i++)
     {
         if (b[f[i]]>=d[1])
          {
              f1[i]=f1[i-1];
              continue;
          }
         f1[i]=f1[i-1]+b[f[i]]-d[1]; 
         d[1]=b[f[i]];
        down(1); 
     }
    memset(d,0,sizeof d);
    for (int i=m;i>m-n/2;i--)d[m-i+1]=b[f[i]],f2[i]=f2[i+1]+b[f[i]];
    for (int i=1;i<=n/2;i++)up(i);    
    for (int i=m-n/2;i;i--)
     {
         if (b[f[i]]>=d[1])
          {
              f2[i]=f2[i+1];
              continue;
          }
         f2[i]=f2[i+1]+b[f[i]]-d[1]; 
         d[1]=b[f[i]];
        down(1);          
     }  
    for (int i=m-n/2;i>n/2;i--)
     if (F>=f1[i-1]+f2[i+1]+b[f[i]])
      {
          printf("%d",a[f[i]]);
          return 0;
      }
    puts("-1");
    return 0;  
} 
#include <bits/stdc++.h>
using namespace std;
typedef double ld;
const int N=305;
const ld eps=1e-15;
int n,m,mp[N][N],du[N];
ld f[N][N],sum,P,Q;
int main()
{
    freopen("dotp.in","r",stdin);
    freopen("dotp.out","w",stdout);
    scanf("%d%d%lf%lf",&n,&m,&P,&Q);
    for(int i=1,x,y;i<=m;i++)
     {
        scanf("%d%d",&x,&y);
        mp[x][y]++;mp[y][x]++;
        du[x]++;du[y]++;
     }
    f[1][n+1]=1;
    for(int i=1;i<=n;i++)
     {
        f[i][i]=1;
        for(int j=1;j<=n;j++)
         if(mp[i][j])f[i][j]+=((ld)P/Q-1)/du[j]*mp[i][j];
     }
    for(int i=1;i<=n;i++)
     {
        int t=i;
        for(int j=i;j<=n;j++)
         if(fabs(f[j][i])>eps)t=j;
        for(int j=1;j<=n+1;j++)swap(f[i][j],f[t][j]);
        for(int j=1;j<=n;j++)
         if(j!=i&&fabs(f[j][i])>eps)
          {
            ld t=f[j][i]/f[i][i];
            for(int k=1;k<=n+1;k++)f[j][k]-=f[i][k]*t;
          }
     }
    for(int i=1;i<=n;i++)sum+=(f[i][i]=f[i][n+1]/f[i][i]);
    for(int i=1;i<=n;i++)printf("%.9lf\n",(double)(f[i][i]/sum+eps));
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=30;
int a[N][N],b[N][N],A,B,ans[N],x[N],dep,n;
void DFS(int u)
{
    if (A+B>dep)return;
    if (u>n)
     {
        for (int i=1;i<=A;i++)
         if (*a[i]<2)return;
        for (int i=1;i<=B;i++)
         if (*b[i]<2)return;
        printf("%d\n",dep);
        exit(0);
     }
    int v=0;
    for (int i=1;i<=A;i++)
     if (a[i][*a[i]]<=x[u]&&(!v||a[v][*a[v]]<a[i][*a[i]]))v=i;
    if (!v)
     {
        ++A;
        a[A][++*a[A]]=x[u];
        ans[u]=A;
        DFS(u+1);
        --*a[A--];
     }
    else
     {
        a[v][++*a[v]]=x[u];
        ans[u]=v;
        DFS(u+1);
        --*a[v];
     }
    v=0;
    for (int i=1;i<=B;i++)
     if (b[i][*b[i]]>=x[u]&&(!v||b[v][*b[v]]>b[i][*b[i]]))v=i;
    if (!v)
     {
        ++B;
        b[B][++*b[B]]=x[u];
        ans[u]=dep+1-B;
        DFS(u+1);
        --*b[B--];
     }
    else
     {
        b[v][++*b[v]]=x[u];
        ans[u]=dep+1-v;
        DFS(u+1);
        --*b[v];
     }
}
int main()
{
    freopen("sequence.in","r",stdin);
    freopen("sequence.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=n;i++)scanf("%d",&x[i]);
    for (dep=1;dep*2<=n;dep++)
      {
        memset(a,0,sizeof a);
        memset(b,0,sizeof b);
        A=B=0;
        DFS(1);
     }
    puts("0");    
    return 0;
}

 

第n+1次考试

原文:http://www.cnblogs.com/xuanyiming/p/7642870.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!