ccf 201809-4 再卖菜

Posted zbhfz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ccf 201809-4 再卖菜相关的知识,希望对你有一定的参考价值。

这题一开始不知道剪枝这种操作,只会傻傻地dfs。

然后dfs递归写80分超时,非递归写70分超时(纳尼?我一直以为非递归算法在时间上会更优秀一些,为什么会这样?!!)

 

剪一下枝就都能过了

技术图片
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 int a[300],b[300];
 7 bool vis[300][300][300];
 8 int n;
 9 bool dfs(int step)
10 
11     if(step==n&&a[n-1]==(b[n-1]+b[n-2])/2)return 1;
12     else if(step==n)return 0;
13     if(step==0)
14         for(int i=1;;i++)
15             b[step]=i;
16             if(dfs(step+1))return 1;
17         
18     
19     int k=3;
20     if(step==1)k-=1;
21     for(int i=a[step-1]*k;i<a[step-1]*k+k;i++)
22         b[step]=i-b[step-1];
23         if(k==3)b[step]-=b[step-2];
24         if(vis[step][b[step-1]][b[step]])continue;
25         else vis[step][b[step-1]][b[step]]=1;
26         if(b[step]>0&&dfs(step+1))return 1;
27     
28     return 0;
29 
30 int main()
31 
32     cin>>n;
33     for(int i=0;i<n;i++)scanf("%d",a+i);
34     dfs(0);
35     cout<<b[0];
36     for(int i=1;i<n;i++)printf(" %d",b[i]);
37     return 0;
38 
递归算法
技术图片
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<stack>
 5 using namespace std;
 6 typedef long long ll;
 7 int a[300],b[300],k[300],i[300];
 8 bool vis[300][300][300];
 9 int n;
10 void dfs(int step=0)
11 
12     stack<int>st;
13     st.push(step);
14     while(1)
15         step=st.top();
16         if(step==n&&a[n-1]==(b[n-1]+b[n-2])/2)return;
17         else if(step==n)
18             st.pop();
19             continue;
20          
21         if(step==0)
22             b[step]+=1;
23             st.push(step+1);
24             continue;
25         
26         i[step]++;
27         if(!k[step])
28             k[step]=3;
29             if(step==1)k[step]-=1;
30             i[step]=a[step-1]*k[step];
31         
32         if(i[step]<a[step-1]*k[step]+k[step])
33             b[step]=i[step]-b[step-1];
34             if(k[step]==3)b[step]-=b[step-2];
35             if(vis[step][b[step-1]][b[step]])continue;
36             else vis[step][b[step-1]][b[step]]=1;
37             if(b[step]>0)st.push(step+1);
38         
39         else
40             st.pop();
41             k[step]=0;
42         
43     
44 
45 int main()
46 
47     cin>>n;
48     for(int i=0;i<n;i++)scanf("%d",a+i);
49     dfs(0);
50     cout<<b[0];
51     for(int i=1;i<n;i++)printf(" %d",b[i]);
52     return 0;
53 
非递归算法

 

以上是关于ccf 201809-4 再卖菜的主要内容,如果未能解决你的问题,请参考以下文章

CCF(再卖菜60分)爆搜+记忆化搜索+差分约束

[csp-201809-4]再卖菜 差分约束or记忆化搜索

CCF-再卖菜-20180904

CCF-CSP 201809 赛题训练

卖菜也能有新招

csp 201809-1 卖菜