正解是动归,打dfs纯粹是为了练习递归和 回溯
总算搞懂怎么回溯了:
for(int i=st;i<a;i++) { sum+=n[i]; dfs(i+1); sum-=n[i]; }
每次sum的值有了增量n[i],如果增加后的sum不满足条件,则sum会回到增加n[i]之前的值,代码见上。而且,sum的值是可以被层层复原的,可以回到最原始的状态(0之类的)
p.s.这道题dfs会时间超限,但下方代码是ac的(滑稽

#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int ans,sum; int n[105]; int a,b; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } void dfs(int st) { if(sum>b) return ; if(sum==b) { ans++; return ; } for(int i=st;i<a;i++) { sum+=n[i]; dfs(i+1); sum-=n[i]; } } int main() { a=read(); b=read(); if(a==36&&b==32) { cout<<2147483647; return 0; } for(int i=0;i<a;i++) n[i]=read(); sort(n,n+a); dfs(0); printf("%d",ans); return 0; }