• 2017/9/27模拟赛


    题解:这题的数据被分成了2部分,我们分类讨论。①n<=40,我们分成前后2部分dfs;②n>40,发现c最大只有20000,所以dp即可。

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #define Mod 1000000007
     4 #define MN 120000005
     5 using namespace std;
     6 int a[105],f[MN],ans,sum,n;
     7 void rw(int&a,int b){if((a+=b)>=Mod) a-=Mod;}
     8 void dfs1(int x,int nn,int k){
     9     if(k>sum) return;
    10     if(x>nn){++f[k]; return;}
    11     dfs1(x+1,nn,k); dfs1(x+1,nn,k+a[x]);
    12 }
    13 void dfs2(int x,int nn,int k){
    14     if(k>sum) return;
    15     if(x>nn){rw(ans,f[sum-k]); return;}
    16     dfs2(x+1,nn,k); dfs2(x+1,nn,k+a[x]);
    17 }
    18 int main()
    19 {
    20     freopen("promonkey.in","r",stdin);
    21     freopen("promonkey.out","w",stdout);
    22     scanf("%d",&n);
    23     for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];
    24     if(sum%2==1){printf("0");return 0;} sum/=2;
    25     if(n>40){
    26         f[0]=1; int x=0;
    27         for(int i=1;i<=n;x+=a[i++])
    28             for(int j=min(sum,x);j>=0;j--) rw(f[j+a[i]],f[j]);
    29         printf("%d",f[sum]);
    30         return 0;
    31     }
    32     else{
    33         dfs1(1,n/2,0); dfs2(n/2+1,n,0);
    34         printf("%d",ans);
    35         return 0;
    36     }
    37 }

    题解:我们二分答案,取向左和向右走的步数的最小值2倍数和最大值之和,若小于当前答案,继续向右拓展,这样如果最后所有的豆子都被吃则满足条件。

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<vector>
     4 using namespace std;
     5 vector<int> a,b;
     6 int n,ans;
     7 int calc(int l,int x,int r){
     8     int aa=x-l,bb=r-x;
     9     return 2*min(aa,bb)+max(aa,bb);
    10 }
    11 bool check(int len){
    12     int i,j,L,R;
    13     for(i=j=0;i<a.size();i++)
    14         for(L=R=a[i];j<b.size();j++){
    15             if(calc(min(L,b[j]),a[i],max(R,b[j]))>len) break;
    16             else L=min(L,b[j]),R=max(R,b[j]);
    17         }
    18     if(j<b.size()) return false;
    19     return true;
    20 }
    21 int main()
    22 {
    23     freopen("pacman.in","r",stdin);
    24     freopen("pacman.out","w",stdout);
    25     scanf("%d
    ",&n);
    26     for(int i=1;i<=n;i++){
    27         char c; scanf("%c",&c);
    28         if(c=='P') a.push_back(i);
    29         if(c=='*') b.push_back(i);
    30     }
    31     int l=1,r=2*n;
    32     while(l<=r){
    33         int mid=l+r>>1;
    34         if(check(mid)) r=mid-1,ans=mid;
    35         else l=mid+1;
    36     }
    37     printf("%d",ans);
    38 }

    题解:没写。

  • 相关阅读:
    MySQL官方文档-二级索引覆盖主键索引
    windows server 2008/win7 远程控制
    博客园美化日记
    MarkDown 中使用 LaTeX 数学式
    DOS命令和bat脚本
    数据链路层
    网络安全
    运输层安全协议SSL
    DNS/域名
    停止等待协议
  • 原文地址:https://www.cnblogs.com/Beginner-/p/7606321.html
Copyright © 2020-2023  润新知