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 }

非递归算法

原文地址:https://www.cnblogs.com/zbhfz/p/11333438.html

时间: 2024-10-05 23:25:25

ccf 201809-4 再卖菜的相关文章

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

201809-4 再卖菜 我使用的是爆搜解决,只得了60分. 记忆化搜索 差分约束 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> using namespace std; int n; int a[303]; int b[303]; bool flag=false; void dfs(int k,int now,

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

先更新第一个做法:差分约束 转化成最长路,求出的每一个解是满足差分方程的最小值 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int N=3100; 5 struct node{ 6 int x,y,d,next; 7 }a[2*N]; 8 int n,al,first[N],b[N],s[N]; 9 bool vis[N]; 10 queue<int> q; 11 12 void ins(int x,int

富二代用微信卖菜,结果悲剧

在黄凯偌大的办公桌上,一只干巴巴的苹果甚是惹眼:拳头大小,表皮发黄,一道道皱褶就像岁月的沟壑,透出点沧桑的味道. "这是我过年时放在这里的,虽然脱水严重,但一点没有腐烂.明显用过防腐剂,还打过蜡."面对记者,1989年出生的黄凯侃侃而谈,"我每天对着这个苹果,就是希望用它来提醒自己,要做安全放心的产品." 10天前,微信卖菜平台正式上线.作为投资者,黄凯打算用四五年时间,改变和他同样年轻的一批金华人的生活习惯:微信点点,健康的蔬菜水果和厨房佐料,就会自动送上门来.

卖菜也能有新招

实习时间:2016/02/05 ——2016/02/24 实习地点:广西省桂林市平乐县菜市 实习报告: 早早学校就放假了,当时也没有找到好的实习工作,所以就先回了家.回家回的早也有早的烦恼,当时朋友同学都还在上学没回家,爸妈就叫我去卖菜了.世界上没有任何事情是可以很轻松做完的,卖菜也一样.卖菜最烦的就是等待,最困的就是早起晚归. 头天下午就去菜地里面把要的菜和菜农们说好,等第二天一大早菜农们就会把菜送到我们卖菜的档口去. 这就是其中一天去地上看的菜. 第二天一大早就去搬菜.摆菜了. 枯燥而无谓的

互联网卖菜,岂止一个自提柜的距离

一直以来,对生鲜电商最大的槽点也就在此--在网上看到的图片与最后到手的货物"长得好像差了那么点意思". 文/张书乐 刊载于<株洲日报>2016年11月21日天台时评版 据<株洲晚报>报道,日前,在天元区共和城等12个小区里,出现了一个别样的储物柜--生鲜自提站.于是乎,株洲有了本地的"网上买菜.家门口取菜"的生鲜电商体验. 先点个赞,在北上广出现了2年有余的生鲜电商,总归还是游到了株洲来.顺便吐个槽,"楼下的小卖部"作为生

CCF-再卖菜-20180904

可以说这道题出的不错,我是用动态规划做的 ( 严谨点说应该是记忆化搜索,我是递归版本,非递归我不会啊... 题意分析: x1  x2  x3 已知 x1+x2=t1或t1+1 x1+x2+x3=t2 | t2+1 | t2+2 x2+x3=t3 |  t3+1 如果我们从x1=1 开始搜索, 那么组成了一颗搜索树 每次有三次分叉, 一共有100层  3^100 太吓人了 还好的是 t1,t2,t3 数据规模不大 我们可以合并很多重复的状态,经行记忆化搜索 那么这道题核心就在于对状态的定义了: 我

201809-1卖菜

满分 #include<stdio.h> int main() { int n; scanf("%d",&n); int i ,j; int a[n],b[n]; for(i=0;i<n;i++) scanf("%d",&a[i]); if(n==2) { b[0]=b[1]=(a[0]+a[1])/2; } else { for(i=1;i<n-1;i++) { b[i]=(a[i-1]+a[i]+a[i+1])/3; }

CCF-CSP刷题库11-18

CCF-CSP刷题库11-18 第十一次认证 201709-1 打酱油 201709-2 公共钥匙盒 201709-3 JSON查询 201709-4 通信网络 第十二次认证 201712-1 最小差值 201712-2 游戏 201712-3 Crontab 201712-4 行车路线 第十三次认证 201803-1 跳一跳 201803-2 碰撞的小球 201803-3 URL映射 201803-4 棋局评估 第十四次认证 201809-1 卖菜 201809-2 买菜 201809-3 元

CCF签到汇总(JAVA版本,2013-12~2018-12)

CCF签到题,没有提到分数的题目都是100分,不然会额外提出,样例输入都单独文本复制粘贴了,这样你们测试的时候很方便粘贴用例,不用自己手敲,都是一些签到题.但有好的基础,会多的数据结构,好的数学思想,那么这些都是一些很简单的问题.因为java版本不多,所以仅供参考,以下代码的思路都很简单,很多都直接通过题目面向过程,有更好的想法,或者你我有些题没有满分的改进方式都可以交流. CCF300分的线,1.2题需要拿满,最低也要190,第三题是理解题,很多时候考你的语文能力更多,第四题是规律性更强的题,