博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uva1625颜色的长度
阅读量:4513 次
发布时间:2019-06-08

本文共 2984 字,大约阅读时间需要 9 分钟。

输入两个长度分别是n和m(n,m<=5000)的颜色序列,要求按顺序合并成同一个序列,即每次可以把一个序列开头的颜色放到新序列的尾部。

例如,两个颜色序列GBBY和YRRGB,至少有两种合并结果:GBYBRYRGB和YRRGGBBYB。对于每种颜色来说其跨度L(c)等于最大位置和最小位置之差。例如,对于上面两种合并结果,每种颜色的L(c)和所有L(c)的总和,如图所示

Color G Y B R -> Sum
L(c)Scenario 1 7 3 7 2 -> 19
L(c)scenario 2 1 7 3 1 -> 12

你的任务是找一种合并方式,使得所有L(c)的总和最小

设f(i,j)表示已经移走了i和j个元素还需要的费用

开始看题不够仔细,瞎推了一个转移方程,f(i,j)=min(f(i-1,j)+n-j+1,f(i,j+1)+n-i+1)

结果:

 

重新推

预处理每个颜色的开始与结束位置,每次累加L(c)值

 

1 #include
2 #include
3 #include
4 using namespace std; 5 const int maxn=5000+5; 6 const int INF=1e9+7; 7 int num[2][maxn],sa[maxn],sb[maxn],ea[maxn],eb[maxn]; 8 int t,t1,t2,n,m,f[2][maxn]; 9 char a[maxn],b[maxn];10 template
void red(t &x)11 {12 x=0;13 int w=1;14 char ch=getchar();15 while(ch<'0'||ch>'9')16 {17 if(ch=='-')18 w=-1;19 ch=getchar();20 }21 while(ch>='0'&&ch<='9')22 {23 x=(x<<3)+(x<<1)+ch-'0';24 ch=getchar();25 }26 x*=w;27 }28 void input()29 {30 freopen("input.txt","r",stdin);31 }32 int main()33 {34 //input();35 red(t);36 while(t--)37 {38 scanf("%s",a+1);39 scanf("%s",b+1); 40 n=strlen(a+1);41 m=strlen(b+1);42 memset(f,0,sizeof(f));43 //memset(color,0,sizeof(color));44 //memset(q,0,sizeof(q));45 memset(num,0,sizeof(num));46 memset(sa,0x3f,sizeof(sa));47 memset(sb,0x3f,sizeof(sb));48 memset(ea,0,sizeof(ea));49 memset(eb,0,sizeof(eb));50 for(int i=1;i<=n;++i)51 {52 a[i]-='A';53 sa[a[i]]=min(sa[a[i]],i);54 ea[a[i]]=i;55 }56 for(int i=1;i<=m;++i)57 {58 b[i]-='A';59 sb[b[i]]=min(sb[b[i]],i);60 eb[b[i]]=i;61 }62 for(int i=0;i<=n;++i)63 for(int j=0;j<=m;++j)64 {65 if(!i&&!j)66 continue;67 t1=t2=0x3f3f3f3f;68 if(i)69 t1=f[(i-1)%2][j]+num[(i-1)%2][j];70 if(j)71 t2=f[i%2][j-1]+num[i%2][j-1];72 f[i%2][j]=min(t1,t2);73 if(i)74 {75 num[i%2][j]=num[(i-1)%2][j];76 if(sa[a[i]]==i&&sb[a[i]]>j)77 ++num[i%2][j];78 if(ea[a[i]]==i&&eb[a[i]]<=j)79 --num[i%2][j];80 }81 else if(j)82 {83 num[i%2][j]=num[i%2][j-1];84 if(sb[b[j]]==j&&sa[b[j]]>i)85 ++num[i%2][j];86 if(eb[b[j]]==j&&ea[b[j]]<=i)87 --num[i%2][j];88 }89 }90 printf("%d\n",f[n%2][m]); 91 }92 return 0;93 }
View Code

 

转载于:https://www.cnblogs.com/Achensy/p/10843632.html

你可能感兴趣的文章
HDU 3899 树形DP
查看>>
继承上机作业
查看>>
设计模式 4/23 建造者模式
查看>>
Logging in Java
查看>>
leetcode算法:Distribute Candies
查看>>
机器学习之路: python 朴素贝叶斯分类器 MultinomialNB 预测新闻类别
查看>>
LINUX 忘记root密码
查看>>
json转换成Map
查看>>
MySQL查看当前用户、存储引擎、日志
查看>>
tpcc-mysql 系列二:进行TPCC测试
查看>>
将16进制的颜色值变成UIColor
查看>>
[转]magento 2 modes – 每种模式的特点及如何切换(翻译)
查看>>
求n的阶乘【VB代码实现】
查看>>
VSCode(Visual Studio Code) 自用插件
查看>>
NOIp2016纪录[那些我所追求的]
查看>>
(VB)定时更换(IE)代理IP(代理轮换)
查看>>
Node.js HTTP Server对象及GET、POST请求
查看>>
LintCode Coins in a Line
查看>>
[题解]POJ 3207 Ikki's Story IV - Panda's Trick
查看>>
Translate Animation
查看>>