简单dp训练1
来源:互联网 发布:淘宝怎么测图 编辑:程序博客网 时间:2024/05/14 15:04
2017年08月13日 基础dp训练
1:
思路 最大子矩阵和的方法和最大字段和一样
可是我一开始还是不会。。
int a[mxn][mxn];int sum[mxn][mxn];int main(){ int n; while(~sf("%d",&n)){ mem(sum[0],0); for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ sf("%d",&a[i][j]); sum[i][j]=sum[i-1][j]+a[i][j]; } } int ans=-inf; for(int i=1;i<=n;++i){ for(int j=i;j<=n;++j){ int t=0; for(int k=1;k<=n;++k){ t+=sum[j][k]-sum[i][k]; ans=max(ans,t); if(t<0)t=0; } } } pf("%d\n",ans); }}
2:https://vjudge.net/contest/177552#problem/F
太坑了。。。
吧int 改为short 这样就不会爆内存。。。
char s[mxn];short dp[mxn][mxn];int main(){ int n; while(~sf("%d",&n)){ sf("%s",s+1); for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ if(j<=i)dp[i][j]=0; else dp[i][j]=6000; } } for(int len=2;len<=n;++len){ for(int i=1;i<=n-len+1;++i){ int j=i+len-1; if(s[i]==s[j])dp[i][j]=dp[i+1][j-1]; if(dp[i+1][j]+1<dp[i][j])dp[i][j]=dp[i+1][j]+1; if(dp[i][j-1]+1<dp[i][j])dp[i][j]=dp[i][j-1]+1; //dp[i][j]=min(dp[i][j],min(dp[i+1][j]+1,dp[i][j-1]+1)); //pf("%d ",dp[i][j]); } } cout<<dp[1][n]<<'\n'; }}
还是学师兄的吧。。用的是吧 字符串反过来,变为求LCS。。。
然后用滚动数组优化
char s[mxn];int dp[2][mxn];int main(){ int n; while(~sf("%d",&n)){ sf("%s",s+1); mem(dp,0); for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ dp[i%2][j]=max(dp[(i+1)%2][j],dp[i%2][j-1]); dp[i%2][j]=max(dp[i%2][j],dp[(i+1)%2][j-1]+(s[i]==s[n-j+1])); } } pf("%d\n",n-dp[n%2][n]); }}
https://vjudge.net/contest/177552#problem/G
这个应该就只是一个很简单的LCS的变形啊。为什么我老是觉的空字符没法处理。。。
char s[mxn],t[mxn];int dp[mxn][mxn];int val[5][5]={ 5,-1,-2,-1,-3, -1,5,-3,-2,-4, -2,-3,5,-2,-2, -1,-2,-2,5,-1, -3,-4,-2,-1,-5};int f(char x){ if(x=='A') return 0; if(x=='C') return 1; if(x=='G') return 2; if(x=='T') return 3; if(x==' ') return 4;}int main(){ int T;sf("%d",&T); while(T--){ int n,m; sf("%d %s",&n,s+1);sf("%d %s",&m,t+1); for(int i=1;i<=n;++i) dp[i][0]=dp[i-1][0]+val[f(s[i])][f(' ')]; for(int i=1;i<=m;++i) dp[0][i]=dp[0][i-1]+val[f(t[i])][f(' ')]; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ dp[i][j]=max(dp[i-1][j]+val[f(s[i])][f(' ')],dp[i][j-1]+val[f(t[j])][f(' ')]); dp[i][j]=max(dp[i-1][j-1]+val[f(s[i])][f(t[j])],dp[i][j]); } } pf("%d\n",dp[n][m]); }}
https://vjudge.net/contest/177552#problem/J
两边弄一下LIS。。
顺便回顾下那个二分法的LIS
double a[N];double g1[N],g2[N];int dp1[N],dp2[N];int main(){ int n; while(~sf("%d",&n)){ mem(dp1,0);mem(dp2,0); for(int i=1;i<=n;++i)g1[i]=inf,g2[i]=inf; rep(i,1,n)sf("%lf",&a[i]); for(int i=1;i<=n;++i){ int k=lower_bound(g1+1,g1+1+n,a[i])-g1; g1[k]=a[i]; dp1[i]=k; } for(int i=n;i>=1;--i){ int k=lower_bound(g2+1,g2+1+n,a[i])-g2; g2[k]=a[i]; dp2[i]=k; } int ans=0; for(int i=1;i<=n;++i){ for(int j=i+1;j<=n;++j){ ans=max(ans,dp1[i]+dp2[j]); } } pf("%d\n",n-ans); }}
这题做过,,这次差一点。。我不应该a[i]-=15,… 都不知道自己为什么要这样。。
http://blog.csdn.net/libin56842/article/details/21116143
int a[N],b[N];int dp[25][M];int main(){ int n,m; while(~sf("%d%d",&n,&m)){ rep(i,1,n){sf("%d",&a[i]);} rep(i,1,m){ sf("%d",&b[i]); } mem(dp,0);dp[0][8000]=1; for(int i=1;i<=m;++i){ for(int j=0;j<=16000;++j){//平衡的地方。。 if(dp[i-1][j]){//优化,有没有都可以,更快。 for(int k=1;k<=n;++k){ dp[i][j+b[i]*a[k]]+=dp[i-1][j];//注意方向 } } } } pf("%d\n",dp[m][8000]); }}
https://vjudge.net/contest/177552#problem/O
不会。。没想都居然最后真的一个一个枚举当前的是不是合适的。
int a[N],c[N];bool dp[M];int sum[M];int main(){ int n,m; while(~sf("%d%d",&n,&m)&&n+m){ rep(i,1,n){sf("%d",&a[i]);} rep(i,1,n){sf("%d",&c[i]);} mem(dp,false); int ans=0;dp[0]=true; for(int i=1;i<=n;++i){ mem(sum,0); for(int j=a[i];j<=m;++j){ if(!dp[j]&&dp[j-a[i]]&&sum[j-a[i]]<c[i]){ dp[j]=true; sum[j]=sum[j-a[i]]+1; ++ans; } } } pf("%d\n",ans); }}
https://vjudge.net/contest/177552#problem/P
不懂为何这题又是前推式才过了。。。我的有什么错误码。。。
可能我的题意没搞清楚,应该每一个组都要有一个花的。(还真的是。)
int a[N][N];int dp[N][N];int main(){ int n,m; while(~sf("%d%d",&n,&m)){ rep(i,1,n){ rep(j,1,m){ sf("%d",&a[i][j]); } } mem(dp,0); int ans=0; for(int i=1;i<=n;++i)dp[i][i]=dp[i-1][i-1]+a[i][i]; for(int i=1;i<=n;++i){ for(int j=i+1;j<=m;++j){ dp[i][j]=max(dp[i][j-1],dp[i-1][j-1]+a[i][j]); } } /* for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ dp[i][j]=max(dp[i][j-1],max(dp[i][j],dp[i-1][j-1]+a[i][j])); } }*/ pf("%d\n",dp[n][m]); }}
https://vjudge.net/contest/177552#problem/Q
这题感觉枚举起点和终点会炸。。而且我的代码太丑了。。
看了师兄的。。挺好的。。
char t[N];char word[N*2][N];int len[N*2];int dp[N];int main(){ int l,m; while(~sf("%d%d",&m,&l)){ sf("%s",t+1); rep(i,1,m){sf("%s",word[i]+1);len[i]=strlen(word[i]+1);} for(int i=1;i<=l;++i){ dp[i]=dp[i-1]; for(int j=1;j<=m;++j){ if(i>=len[j]&&word[j][len[j]]==t[i]){ int r=i-1,tmp=len[j]-1; while(r&&tmp)if(word[j][tmp]==t[r--])--tmp; if(!tmp&&dp[r]+len[j]>dp[i])dp[i]=dp[r]+len[j]; } } } pf("%d\n",l-dp[l]); }}
阅读全文
0 0
- 简单dp训练1
- 2016 SCUT 专题训练 简单dp
- 退役前的简单dp训练
- hdu1024 scut训练1 dp
- dp训练
- 周六日常训练,背包dp,树形dp,简单dp以及很多数学?
- 蒟蒻DP专题训练1--HDU2955
- ACM DP训练专辑
- 树DP训练专辑
- 【总结】121014DP训练
- dp训练 1005
- dp训练 1003
- dp训练 1004
- 寒假训练DP
- ACdream DP专题训练
- Oxer的dp训练
- POJ DP训练计划
- dp专题训练
- JZOJ2017.08.07 C组
- java单例模式
- linux 上安装和设置mvn
- UVa 11059 最大乘积(水)
- zookeeper 二: snap file和配置
- 简单dp训练1
- string&vector阅读小测试
- 三栏布局
- 生成验证码图片(一)
- Android应用开发—LayoutParams的用法
- swift--ViewController.swift
- 别人结婚了!你在干嘛?
- View Animation补间动画
- H5常用单词及标签、属性