zoukankan      html  css  js  c++  java
  • BZOJ 1789&1830 推式子 乱搞

    把思路理顺了就行了… 下面把整个乱搞思路讲一下。
    三条项链首先考虑最里面的那个珠子。如果不是完全相同的话,就需要把所有项链的所有珠子全都拆下来——这也就是全部过程,如果再装的话也是浪费。然后如果完全相同的话,就考虑倒数第二个珠子,一样的思维方式。因此,我们要找到的就是从里到外第一个不完全相同的珠子,这一段可以直接忽略。
    然后我们先考虑两条项链的情形:很明显,最优方案就是一直拆,拆到完全相同为止。然后我们加入第三条项链,这时候也要一直拆,一直拆到底(因为经过之前的步骤,三条项链的最里面的珠子不完全相同),然后往回补,一直补到前两条项链的最长公共前缀处。这样不难证明是最优的。这时,$$Ans=Len_A+Len_B+Len_C-d$$其中(d)是前两条相连的最大公共前缀。最后的问题就是谁是“前两条项链”——枚举即可,取(d)的最大值,即可获得(Ans)的最小。这道题的思考方式和1787有点像(那题是三个点的LCA),也是AHOI的题。
    代码的细节需要注意(略丑…)

    // BZOJ 1789
    
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
     #define rep(i,a,b) for (int i=a; i<=b; i++)
     #define read(x) scanf("%d", &x)
     const int INF=0x3f3f3f3f;
    
     char st[4][50+5];
     int same, len[4];
    
     int check(int x, int y) {
     	int ret=1;
     	if (len[x]>len[y]) swap(x, y);
     	while (ret+same<=len[x] && st[x][ret+same]==st[y][ret+same]) ret++;
     	return ret-1;
     }
    
    int main()
    {
    	int ml=INF;
    	rep(i,1,3) read(len[i]), ml=min(ml, len[i]), scanf("%s", st[i]+1);
    	rep(i,1,ml) 
               if (!((st[1][i]==st[2][i]) && (st[1][i]==st[3][i]))) break; else same=i;
    	int d=max(max(check(1, 2), check(1, 3)), check(2, 3));
    	int ans=len[1]+len[2]+len[3]-d-3*same;
    	printf("%d
    ", ans);
    }
    
    
    
  • 相关阅读:
    Docker入门(windows版),利用Docker创建一个Hello World的web项目
    SpringBoot集成JWT实现token验证
    Jedis的基本操作
    Java动态代理详解
    SpringBoot利用自定义注解实现通用的JWT校验方案
    递归——汉诺塔问题(python实现)
    Datatable删除行的Delete和Remove方法的区别
    C# DEV使用心得
    总结
    安装插件时
  • 原文地址:https://www.cnblogs.com/yearwhk/p/5122320.html
Copyright © 2011-2022 走看看