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",&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 }

 

题解:没写。

 

转载于:https://www.cnblogs.com/Beginner-/p/7606321.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值