0x53 区间DP
石子合并 搞笑
#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\n",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\n",mmax);for(int i=1;i<=aslen;i++)printf("%d ",as[i]);printf("\n");}return 0; } poj1179金字塔 怎么這里的題要么簡單得要死要么難得要死啊 這個搜索順序就。。和樹上差分沒撒區別嘛,我的想法是區間視作子樹合并就乘起來
雖然想法好像很對而我還是太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\n",dfs(1,strlen(ss+1)));return 0; } 金字塔?
轉載于:https://www.cnblogs.com/AKCqhzdy/p/9457190.html
總結
- 上一篇: exception javax.cryp
- 下一篇: MyBatis的几个重要概念和工作流程