DP小合集
1.Uva1625颜色的长度
dp[i][j]表示前一个串选到第i个 后一个串选到第j个 的最小价值
记一下还有多少个没有结束即dp2
记一下每个数开始和结束的位置
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<iostream>
- using namespace std;
- char s1[],s2[];
- int fp[],fq[],ep[],eq[];
- const int INF=;
- int dp1[][],dp2[][];
- int main()
- {
- //freopen("color.in","r",stdin);
- //freopen("color.out","w",stdout);
- //写了个意义不明的滚动数组。。。
- //BGM:Hop
- scanf("%s%s",s1+,s2+);
- int n=strlen(s1+),m=strlen(s2+);
- for(int i=;i<=n;i++)s1[i]-='A';
- for(int i=;i<=m;i++)s2[i]-='A';
- for(int i=;i<;i++)fp[i]=fq[i]=INF;
- for(int i=;i<=n;i++)
- {
- fp[s1[i]]=min(fp[s1[i]],i);
- ep[s1[i]]=i;
- }
- for(int i=;i<=m;i++)
- {
- fq[s2[i]]=min(fq[s2[i]],i);
- eq[s2[i]]=i;
- }
- int cur=;
- for(int i=;i<=n+;i++)
- {
- for(int j=;j<=m+;j++)
- {
- if(!i && !j)continue;
- int v1=INF,v2=INF;
- if(i)v1=dp1[cur^][j]+dp2[cur^][j];
- if(j)v2=dp1[cur][j-]+dp2[cur][j-];
- dp1[cur][j]=min(v1,v2);
- if(i)
- {
- dp2[cur][j]=dp2[cur^][j];
- if(fp[s1[i]]==i&&fq[s1[i]]>j)dp2[cur][j]++;
- if(ep[s1[i]]==i&&eq[s1[i]]<=j)dp2[cur][j]--;
- }
- else if(j)
- {
- dp2[cur][j]=dp2[cur][j-];
- if(fq[s2[j]]==j&&fp[s2[j]]>i)dp2[cur][j]++;
- if(eq[s2[j]]==j&&ep[s2[j]]<=i)dp2[cur][j]--;
- }
- }
- cur=cur^;
- }
- cout<<dp1[cur^][m];
- return ;
- }
意义不明的滚动数组
2.Uva12563劲歌金曲
首先留出1s来唱最后一首歌
剩下的简单的背包+记录路径
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<iostream>
- using namespace std;
- const int MAXN=;
- int n,T;
- int a[MAXN];
- int w[];
- int b[MAXN];
- int main()
- {
- freopen("party.in","r",stdin);
- freopen("party.out","w",stdout);
- cin>>n>>T;
- for(int i=;i<n;i++)cin>>w[i];
- T=min(T,);
- T--;//长者续命-1s 苟利国家生死以岂因祸福避趋之 敢同恶鬼争高下,不向霸王让寸分
- //你们啊Naive!你们有一个好 全世界到哪个地方你们比其他的西方记者跑的还快
- //美国的华莱士不知比你们高到哪里去了我跟他谈笑风生
- sort(w,w+n);
- for(int i=;i<n;i++)
- for(int j=T;j>=w[i];j--)
- if((b[j]<b[a[j-w[i]]]+) || (b[j]==b[a[j-w[i]]]+ && a[j]<a[j-w[i]]+w[i]) )
- {
- a[j]=a[j-w[i]]+w[i];
- b[j]=b[a[j-w[i]]]+;
- }
- b[T]++;
- cout<<b[T]<<" "<<a[T]+;
- return ;
- }
-1s很重要
3.回文子串
把一个字符串切成若干回文子串 问最少切多少个
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<iostream>
- using namespace std;
- const int MAXN=;
- const int INF=;
- int dp[MAXN];
- char s[MAXN];
- bool judge(int i,int j)
- {
- while(i<j)if(s[i++]!=s[j--])return false;
- return true;
- }
- int main()
- {
- freopen("string.in","r",stdin);
- freopen("string.out","w",stdout);
- scanf("%s",s+);
- dp[]=;
- int len=strlen(s+);
- for(int i=;i<=len;i++)dp[i]=INF;
- for(int i=;i<=len;i++)
- for(int j=;j<=i;j++)
- if(judge(j,i))dp[i]=min(dp[i],dp[j-]+);
- printf("%d\n",dp[len]);
- return ;
- }
直接上代码吧= =
4.切木棍
有一个长为L的棍子,还有n个切割点的位置(按从小到大排列)。你的任务是在这些切割点的位置处把棍子切成n+1部分,使得总切割的费用最少。每次切割的费用等于被切割的木棍长度。
区间dp
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<iostream>
- using namespace std;
- int l,n;
- const int inf=;
- int dp[][];
- int a[];
- int main()
- {
- freopen("stick.in","r",stdin);
- freopen("stick.out","w",stdout);
- scanf("%d%d",&l,&n);
- for(int i=;i<=n;i++)scanf("%d",&a[i]);a[]=;a[n+]=l;
- sort(a+,a+n+);
- for(int len=;len<=n+;len++)
- for(int i=;i<=n+-len;i++)
- {
- dp[len][i]=inf;
- for(int j=;j<=len-;j++)dp[len][i]=min(dp[len][i],dp[j][i]+dp[len-j][i+j]+a[len+i]-a[i]);
- }
- cout<<dp[n+][];
- }
似乎发过的= =
5.走过去再走回来
给定平面上n个点(横坐标严格递增)你要从最左边走到最右边再走回来 走欧几里得距离 而且要求每个点都走到 求走的最短路
一开始到洗手间数学证明了半天。。。后来发现还是鸡神设计的状态好(Orz Jackyyc)
dp[i][j]表示前面的人走到i 后面的人走到j 且1~i每个点都走过了
然后记忆化搜索嗖嗖嗖就出来了
再次Orz Jackyyc
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- inline int read()
- {
- char ch=getchar();
- int x=,f=;
- while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
- while(isdigit(ch)){x=*x+ch-'';ch=getchar();}
- return x*f;
- }
- const double eps=1e-;
- struct point
- {
- double x,y;
- }p[];
- double d(point a,point b)
- {
- double ans=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
- return ans;
- }
- int n;
- double dp[][];
- double dis[][];
- double Dp(int a,int b)
- {
- if(dp[a][b])return dp[a][b];
- else return dp[a][b]=min(Dp(a+,b)+dis[a][a+],Dp(a+,a)+dis[b][a+]);
- }
- int ans=2147483647.0;
- int main()
- {
- freopen("route.in","r",stdin);
- freopen("route.out","w",stdout);
- n=read();
- for(int i=;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
- for(int i=;i<=n;i++)for(int j=;j<=n;j++)dis[i][j]=d(p[i],p[j]);
- for(int i=;i<n-;i++)dp[n-][i]=dis[n-][n]+dis[i][n];
- double ans=Dp(,);
- printf("%.2lf",ans);
- return ;
- }
6.城市里的间谍uva1025
预处理比较烦
judge[t][i][0]表示在时间t 车站i 有一个向左开的车
judge[t][i][1]表示在时间t 车站i 有一个向右开的车
对于每个时间 有三个决策 不动 朝左 朝右
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- inline int read()
- {
- char ch=getchar();
- int x=,f=;
- while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
- while(isdigit(ch)){x=*x+ch-'';ch=getchar();}
- return x*f;
- }
- const int INF=;
- int n,m,T,M;
- const int maxn=;
- int t[maxn],d[maxn],D[maxn];
- bool judge[maxn][maxn][];
- int dp[maxn][maxn];
- int main()
- {
- freopen("spy.in","r",stdin);
- freopen("spy.out","w",stdout);
- scanf("%d%d",&n,&T);
- for(int i=;i<=n-;i++)scanf("%d",&t[i]);
- scanf("%d",&m);
- for(int i=;i<=m;i++)
- {
- scanf("%d",&d[i]);
- int te=d[i];
- if(d[i]<T)judge[d[i]][][]=;
- for(int j=;j<=n-;j++)
- {
- if(te+t[j]<=T)
- {
- judge[te+t[j]][j+][]=;
- te=te+t[j];
- }
- else break;
- }
- }
- scanf("%d",&M);
- for(int i=;i<=M;i++)
- {
- scanf("%d",&D[i]);
- int te=D[i];
- if(D[i]<T)judge[D[i]][n][]=;
- for(int j=n-;j>=;j--)
- {
- if(te+t[j]<=T)
- {
- judge[te+t[j]][j][]=;
- te=te+t[j];
- }
- else break;
- }
- }
- for(int i=;i<=n-;i++)dp[T][i]=INF;
- dp[T][]=;
- for(int i=T-;i>=;i--)
- {
- for(int j=;j<=n;j++)
- {
- dp[i][j]=dp[i+][j]+;
- if(j<n && judge[i][j][] && i+t[j]<=T)dp[i][j]=min(dp[i][j],dp[i+t[j]][j+]);
- if(j> && judge[i][j][] && i+t[j-]<=T)dp[i][j]=min(dp[i][j],dp[i+t[j-]][j-]);
- }
- }
- if(dp[][]>=INF)cout<<"impossible";
- else cout<<dp[][];
- }
DP小合集的更多相关文章
- C#的winform小合集
C#的winform小合集 博主很懒,又想记录一下自己的所做所为,仅此而已,供自己日后所看.这个是博主自主学习C#所写的一些小程序,有好玩的,也有一些无聊闲得蛋疼所作的. 内容介绍 C#入门窗口输出h ...
- DP小题集
P2736 "破锣摇滚"乐队 Raucous Rockers 你刚刚继承了流行的"破锣摇滚"乐队录制的尚未发表的N(1 <= N <= 20)首歌的 ...
- Linux入门搭建可视化桌面环境小合集virtual box centOS7.10
常用命令: 关联主机与虚拟机(方便文件共享): # sudo mount -t vboxsf share(主机文件夹名) /usr/share(虚拟机内自创) Linux shell进入root模式: ...
- Codeforces - tag::dp 大合集 [占坑 6 / inf]
Gym - 100753J 某国家仅有金币和银币两种货币,起汇率为g,纪念品市场有n个商人和商品,商人结帐只用银币,并且把一堆银币装在袋子里,分为三种类型,分别按向下/向上/四舍五入取整(其中向上的优 ...
- 关于Hive中常用函数需要注意的点小合集
1.COALESCE( value1,value2,... ) The COALESCE function returns the fist not NULL value from the list ...
- codeforces 888A/B/C/D/E - [数学题の小合集]
这次CF不是很难,我这种弱鸡都能在半个小时内连A四道……不过E题没想到还有这种折半+状压枚举+二分的骚操作,后面就挂G了…… A.Local Extrema 题目链接:https://cn.vjudg ...
- dp合集 广场铺砖问题&&硬木地板
dp合集 广场铺砖问题&&硬木地板 很经典了吧... 前排:思想来自yali朱全民dalao的ppt百度文库免费下载 后排:STO朱全民OTZ 广场铺砖问题 有一个 W 行 H 列的广 ...
- 9.15 DP合集水表
9.15 DP合集水表 显然难了一些啊. 凸多边形的三角剖分 瞄了一眼题解. 和蛤蛤的烦恼一样,裸的区间dp. 设f[i][j]表示i~j的点三角剖分最小代价. 显然\(f[i][i+1]=0,f[i ...
- 微信小程序解决方案合集
微信小程序解决方案合集:http://www.wxapp-union.com/special/solution.html 跳坑系列:http://www.wxapp-union.com/forum.p ...
随机推荐
- MySQL的基本操作--第一弹
前言:在听许嵩,忆当年,意气风发 ———————————————————————————————————————————————— 好了,今天和大家同步讲解mysql的知识了.都是最基本的知识. 一. ...
- (转)linux设备驱动之USB数据传输分析 一
三:传输过程的实现说到传输过程,我们必须要从URB开始说起,这个结构的就好比是网络子系统中的skb,好比是I/O中的bio.USB系统的信息传输就是打成URB结构,然后再过行传送的.URB的全称叫US ...
- 大数据学习系列(5)-- 局域网yum仓库搭建
https://www.cnblogs.com/nulige/p/6081192.html
- mybatis相关
1 namespace dao中使用namespace+id一起来完成对mapper中sql statement的调用. 2 关于resultMap和parameterType parameterTy ...
- TensorFlow_action
安装TensorFlow 包依赖 C:\Users\sas> pip3 install --upgrade tensorflow Collecting tensorflow Downloadi ...
- MySQL合并多行
select id,group_concat(re_id order by re_id separator ",") as re_idfrom tablenamegroup by ...
- lua解析json
自己写的lua解析json,带容错,如果要是用于格式检查,得修改下.很简单直接贴代码 --------------------------------------------------json解析- ...
- 我的Android进阶之旅------>android api的源代码下载地址
Eclipse的SDK Manager不好用,关联不到API的源代码,终于找到一个可以下载API对应的source地址: http://grepcode.com/project/repository. ...
- 让Editplus支持sql语法高亮显示
版权声明:作者:jiankunking 出处:http://blog.csdn.net/jiankunking 本文版权归作者和CSDN共同拥有,欢迎转载.但未经作者允许必须保留此段声明,且在文章页面 ...
- python 学习2:生成器,迭代器,装饰器
1.生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万 个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那 ...