石子合并 搞笑
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int s[310]; int f[310][310]; int main() { int n,x; scanf("%d",&n); s[0]=0; for(int i=1;i<=n;i++) scanf("%d",&x), s[i]=s[i-1]+x, f[i][i]=0; for(int L=2;L<=n;L++) { for(int l=1;l+L-1<=n;l++) { int r=l+L-1; f[l][r]=2147483647; for(int i=l;i<r;i++) { f[l][r]=min(f[l][r],f[l][i]+f[i+1][r]+s[r]-s[l-1]); } } } printf("%d ",f[1][n]); return 0; }
poj1179 神经。。出答案的时候n写成n-1wa了两次
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int a[110]; char c[110],sc[110]; int mx[110][110],mn[110][110]; int aslen,as[110]; int main() { int n,x; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) { scanf("%s%d",sc+1,&a[i]); c[i-1]=sc[1]; mx[i][i]=mn[i][i]=a[i]; if(i!=n) { c[i-1+n]=c[i-1]; a[i+n]=a[i]; mx[i+n][i+n]=mn[i+n][i+n]=a[i]; } } for(int L=2;L<=n;L++) { for(int l=1;l+L-1<=2*n-1;l++) { int r=l+L-1; mx[l][r]=-2147483647; mn[l][r]=2147483647; for(int i=l;i<r;i++) { if(c[i]=='t') { mx[l][r]=max(mx[l][r],mx[l][i]+mx[i+1][r]); mn[l][r]=min(mn[l][r],mn[l][i]+mn[i+1][r]); } else { mx[l][r]=max(mx[l][r],max(mx[l][i]*mx[i+1][r],mn[l][i]*mn[i+1][r])); mn[l][r]=min(mn[l][r],min(mx[l][i]*mx[i+1][r],mn[l][i]*mn[i+1][r])); } } } } int mmax=mx[1][n]; aslen=0, as[++aslen]=1; for(int i=2;i<=n;i++) if(mx[i][i+n-1]>mmax) { mmax=mx[i][i+n-1]; aslen=0, as[++aslen]=i; } else if(mx[i][i+n-1]==mmax) as[++aslen]=i; printf("%d ",mmax); for(int i=1;i<=aslen;i++)printf("%d ",as[i]); printf(" "); } return 0; }
金字塔 怎么这里的题要么简单得要死要么难得要死啊 这个搜索顺序就。。和树上差分没撒区别嘛,我的想法是区间视作子树合并就乘起来
虽然想法好像很对而我还是太naive了不会写
对于一个区间[l,r]假如ss[l]==ss[r],那么我们可以把l+1~r-1视作一棵子树
对于当前询问的区间,枚举断点i,l+1~i形成一棵子树,让i+1~r去继续分割,同时,这样可以保证没有重复,因为1~i每次的大小不一样
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const int mod=1e9; char ss[310]; int f[310][310]; int dfs(int l,int r) { if(l>r||ss[l]!=ss[r])return 0; if(l==r)return 1; if(f[l][r]!=-1)return f[l][r]; f[l][r]=0; for(int i=l+1;i<r;i++) f[l][r]=( ((LL)f[l][r]) + ((LL)dfs(l+1,i)) * ((LL)dfs(i+1,r)) )%mod; return f[l][r]; } int main() { scanf("%s",ss+1); memset(f,-1,sizeof(f)); printf("%d ",dfs(1,strlen(ss+1))); return 0; }