標籤:include roo strong space cpp int turn using ios
以前覺得難
想想以前還是naive
然而我還是用的記搜
令人害怕的題也沒那麼難,qwq
\(root(i,j)\)表示區間\([i,j]\)的根。
CODE:
#include<iostream>#include<cstdio>using namespace std;int n, a[31];int f[31][31], root[31][31];int dfs(int l, int r){ if(f[l][r]>0)return f[l][r]; if(r<l)return 1; for(int i=l; i<=r; i++){ int p=dfs(l, i-1)*dfs(i+1, r)+f[i][i]; if(p>f[l][r]) f[l][r]=p, root[l][r]=i; } return f[l][r];}void print(int l, int r){ if(r<l)return; if(l==r){ printf("%d ", l);return; } printf("%d ", root[l][r]); print(l, root[l][r]-1); print(root[l][r]+1, r);}int main(){ scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", &f[i][i]); printf("%d\n", dfs(1, n)); print(1, n); return 0;}
區間DP做法:
#include<iostream>#include<cstdio>using namespace std;int n,v[39],f[47][47],i,j,k,root[49][49];void print(int l,int r){ if(l>r)return; if(l==r){printf("%d ",l);return;} printf("%d ",root[l][r]); print(l,root[l][r]-1); print(root[l][r]+1,r);}int main() { scanf("%d",&n); for( i=1; i<=n; i++) scanf("%d",&v[i]); for(i=1; i<=n; i++) {f[i][i]=v[i];f[i][i-1]=1;} for(i=n; i>=1; i--) for(j=i+1; j<=n; j++) for(k=i; k<=j; k++) { if(f[i][j]<(f[i][k-1]*f[k+1][j]+f[k][k])) { f[i][j]=f[i][k-1]*f[k+1][j]+f[k][k]; root[i][j]=k; } } printf("%d\n",f[1][n]); print(1,n); return 0;}
Luogu1040 加分二叉樹