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 ...
随机推荐
- 七. PHP模式设计----运行及描写叙述任务
1. 解析器模式 //解析器内容类 //用于存放表达式的运算结果,并且能依据传入的表达式返回当初记录的结果 class InterpreterContext{ private $expressions ...
- 初识Modbus TCP/IP-------------C#编写Modbus TCP客户端程序(二)
由于感觉上一次写的篇幅过长,所以新开一贴,继续介绍Modbus TCP/IP的初步认识, 书接上回 3).03(0x03)功能码--------读保持寄存器 请求与响应格式 这是一个请求读寄存器108 ...
- Django之CURD插件
什么是CURD? CURD顾名思义就是create,update,rearch,delete(所谓的增删改查). 当我们接到一个项目的时候,夸夸夸的就写完表结构,然后就一直写增删改查,增删改查,写了一 ...
- 11.Django数据库操作(查)
django.db.models.query.QuerySet1.可迭代2.可切片 官方文档:https://docs.djangoproject.com/en/1.9/ref/models/quer ...
- 读a paper of ICCV 2017 : Areas of Attention for Image Captioning
前言废话,作者说把代码公布在gitub上,但是迟迟没有公布,我发邮件询问代码情况,邮件也迟迟不回,表示很尴尬..虽然种种这些,但是工作还是好工作,这个没的黑,那我们今天就来详细的介绍这篇文章. 导论: ...
- linux基础part3
linux基础 一.linux基本命令归档命令. 1.归档的定义:归档就是把许多文件或目录打包成一个文件. 2.tar命令格式:tar [参数-cxtzjvfpPN] 打包文件名 文件或目录路径 ...
- spring mvc入门教程 转载自【http://elf8848.iteye.com/blog/875830】
目录 一.前言二.spring mvc 核心类与接口三.spring mvc 核心流程图 四.spring mvc DispatcherServlet说明 五.spring mvc 父子上下文的说明 ...
- HDU - 5550 Game Rooms 【DP+前缀和】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5550 题意 一撞大楼有N层楼,然后每层楼都有一部分人喜欢打羽毛球,一部分人喜欢打乒乓球 但是每层楼只能 ...
- PAT 天梯赛 L2-010. 排座位 【并查集】
题目链接 https://www.patest.cn/contests/gplt/L2-010 思路 因为 题意中 朋友的朋友 就是朋友 那么 朋友的关系 用 并查集 保存 但是 敌对关系 只有直接的 ...
- .net序列化与反序列化——提供多次存储对象集后读取不完全解决方案
||问题: 文本文档读取序列化文件时只能读取第一次序列化对象或对象集,而多次序列化存到同一个文本文件中不能完全读取.最近做一个简单的学生管理系统,涉及到多次将学生对象序列化后追加存储到同一个文档中.在 ...