zoukankan      html  css  js  c++  java
  • poj 2817 WordStack (状态dp)

    http://poj.org/problem?id=2817 

    这个题的意思是第一行给出case数N (1 <= N <= 10),然后给出N个单词,每个一行,当输入不是正整数的时候结束。每个单词最多10个字母。
    Sample Input
    5
    abc
    bcd
    cde
    aaa
    bfcde
    0
    要求的是,按任意顺序排列这些单词,可以在单词前面加任意个空格,使得相邻的单词上下对应的字母数目最多,并输出最多是多少。
    Sample Output
    8
    比如sample里面的8,是这样得来的:
    aaa
    abc
     bcd
      cde
    bfcde
    注意只有相邻单词的字母上下对应才算对应。

    /*
    由于每两个串的最大相同 字符数 是一定的,所以 这个我们是要考虑一个排列使 ,公共字符最多


    状态压缩 , dp[i][j]  表示 在 状态 i 时 以  串 j 结尾的 最大 个数
    dp[i][j] = max(dp[k][x]) (x 是没有 被选的 ,k ==  i &(~(1<<x)))


    */

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<set>
      7 #include<map>
      8 #include<queue>
      9 #include<vector>
     10 #include<string>
     11 #define Min(a,b) a<b?a:b
     12 #define Max(a,b) a>b?a:b
     13 #define CL(a,num) memset(a,num,sizeof(a));
     14 #define maxn  520
     15 #define eps  1e-8
     16 #define inf 100000000
     17 
     18 #define ll   __int64
     19 using namespace std;
     20 int len[12];
     21 char word[12][12] ;
     22 int dp[1500][12] ;
     23 int n;
     24 int com[12][12] ;
     25 int  cal(int a,int b)//计算最大 公共字符数
     26 {
     27     int i,j;
     28     int mx = 0;
     29     int sum ;
     30     for(i = 0 ; i  < len[a];i++)
     31     {
     32           sum = 0;
     33         for(j = 0;j + i < len[a] && j < len[b] ;j++)
     34         {
     35 
     36             if(word[a][i + j] == word[b][j]) sum ++;
     37 
     38 
     39         }
     40         if(sum > mx) mx = sum ;
     41     }
     42     for(i = 0;i< len[b];i++)
     43     {
     44         sum = 0;
     45         for(j = 0 ; j + i< len[b] && j< len[a];j++)
     46         {
     47             if(word[b][i + j] == word[a][j])sum ++;
     48 
     49         }
     50         if(sum > mx) mx = sum ;
     51     }
     52     return mx ;
     53 }
     54 int get(int stat ,int k)
     55 {
     56     int  i;
     57     if(stat == 0)  return 0;
     58     if(dp[stat][k]) return dp[stat][k];
     59 
     60     stat &= (~(1<<k)) ;
     61     int mx = 0 ,d;
     62     for(i = 0 ;i < n;i++)
     63     {    int tmp = stat&(~(1<<i)) ;
     64          if(tmp != stat)
     65          {
     66              d = get( tmp ,i) + com[i][k] ;
     67              if(d > mx) mx = d;
     68         }
     69 
     70 
     71     }
     72      dp[stat][k] = mx ;
     73 
     74     return   dp[stat][k] ;
     75 }
     76 int main()
     77 {
     78     int i,j;
     79     while(scanf("%d",&n),n>0)
     80     {
     81         CL(dp,0);
     82         for(i = 0; i < n;i++)
     83         {
     84             scanf("%s",word[i]);
     85             len[i] = strlen(word[i]);
     86         }
     87         for(i = 0; i <n ;i++)
     88         {
     89             for(j = i+1;j<n;j++)
     90             {
     91                 com[i][j] = com[j][i] = cal(i,j);
     92 
     93             }
     94 
     95         }
     96 
     97         /*for(i = 0; i < n;i++)
     98         {
     99             for(j = 0 ; j< n;j++)
    100               printf("%d ",com[i][j]);
    101 
    102             printf("\n");
    103         }*/
    104 
    105         int stat = (1<<n) - 1;
    106 
    107         int ans = 0,tmp;
    108         for(i = 0 ; i < n;i++)
    109         {
    110             tmp = get(stat,i);
    111             if(tmp > ans)ans = tmp ;
    112         }
    113         printf("%d\n",ans);
    114     }
    115 }

     

  • 相关阅读:
    构建之法
    第一阶段SCRUM冲刺
    NABCD项目分析
    结对开发
    梦断代码阅读-04
    梦断代码阅读-05
    移动端疫情展示
    用Python爬取疫情数据
    全球疫情可视化地图
    第二阶段冲刺第三天个人记录
  • 原文地址:https://www.cnblogs.com/acSzz/p/2651243.html
Copyright © 2011-2022 走看看