zoukankan      html  css  js  c++  java
  • NOIP2014-5-24模拟赛

    Problem 1 护花(flower.cpp/c/pas)

    【题目描述】

    约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花朵!为了使接下来花朵的损失最小,约翰赶紧采取行动,把牛们送回牛棚. 牛们从1到N编号.第i只牛所在的位置距离牛棚Ti(1≤Ti≤2000000)分钟的路程,而在约翰开始送她回牛棚之前,她每分钟会啃食Di(1≤Di≤100)朵鲜花.无论多么努力,约翰一次只能送一只牛回棚.而运送第第i只牛事实上需要2Ti分钟,因为来回都需要时间.    写一个程序来决定约翰运送奶牛的顺序,使最终被吞食的花朵数量最小.

    【输入格式】

    第1行输入N,之后N行每行输入两个整数Ti和Di

    【输出格式】

    一个整数,表示最小数量的花朵被吞食

    【样例输入】

    6

    3 1

    2 5

    2 3

    3 2

    4 1

    1 6

    【样例输出】

    86

    【样例解释】

     约翰用6,2,3,4,1,5的顺序来运送他的奶牛

    Problem 2 修剪草坪(mowlawn.cpp/c/pas)

    【题目描述】

    在一年前赢得了小镇的最佳草坪比赛后,FJ变得很懒,再也没有修剪过草坪。现在,
    新一轮的最佳草坪比赛又开始了,FJ希望能够再次夺冠。
    然而,FJ的草坪非常脏乱,因此,FJ只能够让他的奶牛来完成这项工作。FJ有N
    (1 <= N <= 100,000)只排成一排的奶牛,编号为1...N。每只奶牛的效率是不同的,
    奶牛i的效率为E_i(0 <= E_i <= 1,000,000,000)。
    靠近的奶牛们很熟悉,因此,如果FJ安排超过K(1<=K<=N)只连续的奶牛,那么,这些奶牛就会罢工
    去开派对:)。因此,现在FJ需要你的帮助,计算FJ可以得到的最大效率,并且该方案中
    没有连续的超过K只奶牛。

    【输入格式】
    * 第一行:空格隔开的两个整数N和K
    * 第二到N+1行:第i+1行有一个整数E_i

    【输出格式】
    * 第一行:一个值,表示FJ可以得到的最大的效率值。

    【样例输入】

    5 2

    1

    2

    3

    4

    5

    输入解释:

    FJ有5只奶牛,他们的效率为1,2,3,4,5。他们希望选取效率总和最大的奶牛,但是

    他不能选取超过2只连续的奶牛

    【样例输出】

    12

    FJ可以选择出了第三只以外的其他奶牛,总的效率为1+2+4+5=12。

    Problem 3 虫洞(wormhole.cpp/c/pas)

    【题目描述】

    John在他的农场中闲逛时发现了许多虫洞。虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前)。John的每个农场有M条小路(无向边)连接着N (从1..N标号)块地,并有W个虫洞(有向边)。其中1<=N<=500,1<=M<=2500,1<=W<=200。 现在John想借助这些虫洞来回到过去(出发时刻之前),请你告诉他能办到吗。 John将向你提供F(1<=F<=5)个农场的地图。没有小路会耗费你超过10000秒的时间,当然也没有虫洞回帮你回到超过10000秒以前。

    【输入格式】

    * Line 1: 一个整数 F, 表示农场个数。

    * Line 1 of each farm: 三个整数 N, M, W。

    * Lines 2..M+1 of each farm: 三个数(S, E, T)。表示在标号为S的地与标号为E的地中间有一条用时T秒的小路。

    * Lines M+2..M+W+1 of each farm: 三个数(S, E, T)。表示在标号为S的地与标号为E的地中间有一条可以使John到达T秒前的虫洞。

    【输出格式】

    * Lines 1..F: 如果John能在这个农场实现他的目标,输出"YES",否则输出"NO"。

    【样例输入】

    2

    3 3 1

    1 2 2

    1 3 4

    2 3 1

    3 1 3

    3 2 1

    1 2 3

    2 3 4

    3 1 8

    【样例输出】

    NO

    YES


    T1:贪心

    对于牛i和牛i+1,不妨假设之后的牛D的和为x,

    那么如果牛i后运输,吃掉的花为: 2*Ti+1*(x+Di)+2*Ti*x

    如果牛i先运输,吃掉的花为:2*Ti*(x+Di+1)+2*Ti+1*x

    化简得:Ti+1*Di和Ti*Di+1

    牛i后运输⇔Ti+1*Di<Ti*Di+1⇔Di/Ti<Di+1/Ti+1

    所以排序之后使得任何一对牛都满足上述关系式,不可能存在更优解

    注意:开longlong啊,遇到乘法想longlong,要不然爆0真是泪流满面啊~~~

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define MAXN 100005
     6 #define ll long long
     7 using namespace std;
     8 struct Node{
     9     ll T,D;
    10     double p;
    11     Node(){
    12         T=D=0;
    13         p=0;
    14     }
    15 }s[MAXN];
    16 int n;
    17 ll a[MAXN];
    18 bool comp(const Node &p1,const Node &p2){
    19     return (p1.p<p2.p);
    20 }
    21 int main()
    22 {
    23 //    freopen("flower1.in","r",stdin);
    24 //    freopen("my.out","w",stdout);
    25     scanf("%d",&n);
    26     for(int i=1;i<=n;i++){
    27         scanf("%d%d",&s[i].T,&s[i].D);
    28         s[i].p=(double)s[i].D/s[i].T;
    29     }
    30     sort(s+1,s+n+1,comp);
    31     for(int i=1;i<=n;i++){
    32         a[i]=a[i-1]+s[i].D;
    33     }
    34     ll ans=0;
    35     for(int i=n;i>=1;i--){
    36         ans+=(s[i].T*2*a[i-1]);
    37     }
    38     printf("%lld
    ",ans);
    39     return 0;
    40 }
    Code1

    T2:

    朴素dp很好想,滚动后70分

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define MAXN 100005
     6 #define ll long long
     7 using namespace std;
     8 ll f[MAXN];
     9 ll a[MAXN];
    10 int n,K;
    11 int main()
    12 {
    13 //    freopen("data.in","r",stdin);
    14     scanf("%d%d",&n,&K);
    15     for(int i=1;i<=n;i++){
    16         scanf("%lld",&a[i]);
    17     }
    18     for(int i=0;i<n;i++){
    19         ll temp=0;
    20         for(int k=min(i,K);k>=0;k--){
    21             if(k+1<=K){
    22                 f[k+1]=max(f[k+1],f[k]+a[i+1]);
    23             }
    24             temp=max(temp,f[k]);
    25         }
    26         f[0]=max(f[0],temp);
    27     }
    28     ll ans=0;
    29     for(int i=0;i<=K;i++){
    30         ans=max(ans,f[i]);
    31     }
    32     printf("%lld
    ",ans);
    33     return 0;
    34 }
    Code2-1

    正解是dp+单调队列

    正难则反,求扔掉的牛的效率之和

    然后f[i]表示

    对于前i个牛,我们扔掉i,其余都是正常,

    在这种情况下,所有扔掉的牛效率之和的最小值

    那么f[i]=min{f[j]+a[i] | i-k-1<=j<=i-1}

    实际上我们可以认为此方程中,i扔了,j扔了,i和j之间的都选

    然后结果是∑a[i]-min{f[i-k]~f[i]}

    这样状态的定义就具有了单调队列所需的“跳动性”,而不是普通dp的连贯性

    一般dp连贯性固然好,但是优化时也应该学会打破常规,跳出去

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define MAXN 100005
     6 #define ll long long
     7 using namespace std;
     8 ll read(){
     9     ll x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
    11     while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 ll f[MAXN];
    15 int n,k;
    16 ll a[MAXN];
    17 int deq[MAXN];
    18 ll sum;
    19 int main()
    20 {
    21 //    freopen("data.in","r",stdin);
    22     n=read();k=read();
    23     for(int i=1;i<=n;i++){
    24         a[i]=read();
    25         sum+=a[i];
    26     }
    27     int L=1,R=1;
    28     for(int i=1;i<=n;i++){
    29         f[i]=f[deq[L]]+a[i];
    30         while(L<=R&&f[deq[R]]>=f[i]){
    31             R--;
    32         }
    33         deq[++R]=i;
    34         if(i-k-1==deq[L]){
    35             L++;
    36         }
    37     }
    38     ll ans=f[n];
    39     for(int i=n-1;i>=n-k;i--){
    40         ans=min(ans,f[i]);
    41     }
    42     printf("%lld",sum-ans);
    43     return 0;
    44 }
    Code2-2

    T3:

    就是一个判断负环的问题,用dfs_SPFA即可

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define MAXN 505
     6 #define MAXM 3005
     7 using namespace std;
     8 int read(){
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
    11     while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 int first[MAXN],Next[MAXM*2],to[MAXM*2],Val[MAXM*2],cnt;
    15 //double edge
    16 int d[MAXN],b[MAXN];
    17 int n,m,p;
    18 void Add(int x,int y,int w){
    19     Next[++cnt]=first[x];first[x]=cnt;to[cnt]=y;Val[cnt]=w;
    20 }
    21 int SPFA(int x){
    22     //!!!
    23     if(b[x]){
    24         return 1;
    25     }
    26     b[x]=1;
    27     for(int e=first[x];e;e=Next[e]){
    28         int y=to[e],w=Val[e];
    29         if(d[y]>d[x]+w){
    30             d[y]=d[x]+w;
    31             if(SPFA(y)){
    32                 return 1;
    33             }
    34         }
    35     }
    36     b[x]=0;
    37     return 0;
    38 }
    39 void solve(){
    40     memset(first,0,sizeof(first));
    41     memset(Next,0,sizeof(Next));
    42     memset(to,0,sizeof(to));
    43     memset(Val,0,sizeof(Val));
    44     memset(d,0,sizeof(d));
    45     memset(b,0,sizeof(b));
    46     cnt=0;
    47     n=read();m=read();p=read();
    48     for(int i=1;i<=m;i++){
    49         int x,y,w;
    50         x=read();y=read();w=read();
    51         Add(x,y,w);
    52         Add(y,x,w);
    53     }
    54     for(int i=1;i<=p;i++){
    55         int x,y,w;
    56         x=read();y=read();w=read();
    57         Add(x,y,-w);
    58     }
    59     for(int i=1;i<=n;i++){
    60         if(SPFA(i)){
    61             printf("YES
    ");
    62             return ;    
    63         }
    64     }
    65     printf("NO
    ");
    66 }
    67 int main()
    68 {
    69 //    freopen("wormhole.2.in","r",stdin);
    70     int T;
    71     T=read();
    72     for(int i=1;i<=T;i++){
    73         solve();
    74     }
    75     return 0;
    76 }
    Code3
  • 相关阅读:
    Android json操作之取得一个对象
    Uubntu E: Sub-process /usr/bin/dpkg returned an error code问题的解决办法
    转 Android
    Android 将从网络获取的数据缓存到私有文件
    Android 每隔3s更新一次title
    Android UI主线程与子线程
    Android 解析JSON数组
    MySql中的内外联结查询
    MySQL执行外部sql脚本
    Ubuntu 下启动/停止/重启mysql服务
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7624884.html
Copyright © 2011-2022 走看看