zoukankan      html  css  js  c++  java
  • HNU 省赛选拔热身赛City Merger解题报告

    给出不超过14个长度不超过20的字符串,要求出一个包含所有字符串的长字符串的最短的长度,根据题目数据范围可以知道要用状态DP,每个二进制位表示一个字符串,而且需要用二维的,dp[i][j]表示以j为开头的剩下的状态为i的最优值,转移方程也很好写。

    View Code
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #define N 15
      5 #define inf 0x7fffffff
      6 using namespace std;
      7 int dp[1<<15][N];
      8 char str[N][25];
      9 int map[N][N];
     10 int min(int a,int b)
     11 {
     12     return a<b?a:b;
     13 }
     14 bool get(int i,int j)
     15 {
     16     if(strcmp(str[i],str[j])==0)
     17     return true;
     18     int len1=strlen(str[i]);
     19     int len2=strlen(str[j]);
     20     int l,k,p;
     21     for(k=0;k<=len1-len2;k++)
     22     {
     23         for(p=0;p<len2&&k+p<len1;p++)
     24         if(str[i][k+p]!=str[j][p])
     25         break;
     26         if(p==len2)
     27         return true;
     28     }
     29     for(k=0;k<=len2-len1;k++)
     30     {
     31         for(p=0;p<len1&&k+p<len2;p++)
     32         if(str[i][p]!=str[j][k+p])
     33         break;
     34         if(p==len1)
     35         return true;
     36     }
     37     return false;
     38 }
     39 int getlen(int i,int j)//两个字符串连接增加的长度
     40 {
     41     int l,k,p;
     42     int len1=strlen(str[i]);
     43     int len2=strlen(str[j]);
     44     int minlen=min(len1,len2);
     45     for(l=minlen;l>=0;l--)
     46     {
     47         for(k=len1-l,p=0;k<len1&&p<len2;k++,p++)
     48         if(str[i][k]!=str[j][p])
     49         break;
     50         if(k==len1||p==len2)
     51         return len2-l;
     52     }
     53 }
     54 int n;
     55 int dfs(int state,int k)//记忆化搜索的部分
     56 {
     57     if(dp[state][k]!=inf)
     58     return dp[state][k];
     59     if(state==0)
     60     return dp[0][k]=0;
     61     int i,j,sta;
     62     for(i=0;i<n;i++)
     63     {
     64         if(state&(1<<i))
     65         {
     66             sta=state^(1<<i);
     67             dp[state][k]=min(dp[state][k],dfs(sta,i)+map[k][i]);
     68         }
     69     }
     70     return dp[state][k];
     71 }
     72 int main()
     73 {
     74     int i,j;
     75     int minn;
     76     while(scanf("%d",&n)&&n)
     77     {
     78         for(i=0;i<n;i++)
     79         {
     80             scanf("%s",str[i]);
     81             for(j=0;j<i;j++)
     82             {
     83                 if(get(i,j))
     84                 {
     85                     if(strlen(str[i])>strlen(str[j]))//有字符串被另一个包含的时候,把短的字符串直接覆盖掉
     86                     strcpy(str[j],str[i]);
     87                     i--;
     88                     n--;
     89                 }
     90             }
     91         }
     92         for(i=0;i<n;i++)
     93         for(j=0;j<n;j++)
     94         {
     95             map[i][j]=getlen(i,j);
     96         }
     97         for(i=0;i<(1<<n);i++)
     98         for(j=0;j<n;j++)
     99         dp[i][j]=inf;
    100         int state=(1<<n)-1;
    101         minn=inf;
    102         for(i=0;i<n;i++)
    103         {
    104             minn=min(minn,dfs(state^(1<<i),i)+strlen(str[i]));
    105         }
    106         printf("%d\n",minn);
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    Flutter开发环境搭建
    Android自定义View-圆形图片控件
    浅析对象的创建过程
    Java对象占用内存大小--Java对象的内存结构分析
    对AQS的简单理解及自定义锁的实现
    IntelliJ IDEA插件开发的简单流程
    IOC之运行时注入-实现Activity的布局注入+控件注入+事件绑定
    动态代理+注解+反射实现View的点击事件绑定
    Java中的注解和反射
    利用短信通知的方式在Tasker中实现收到Android手机短信自动转发到微信
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2670886.html
Copyright © 2011-2022 走看看