这题一开始不知道剪枝这种操作,只会傻傻地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