zoukankan      html  css  js  c++  java
  • POJ1699 Best Sequence 状态压缩DP

      题目链接:http://poj.org/problem?id=1699

      太爽了这题,1AC。容易想到用状态压缩DP来做,f[k][i][j]表示当前 i 状态有 k 个串并且串以 j 结尾的最短串。则 f[k][i][rt]=Min{ f[k][i][rt] , f[k][st][r]+len[j]+g[r][j] }。其中状态 i 用位运算表示所包含的具体的串,1010表示包含串2和4。这里要注意转移方程中的rt,要考虑串包含的情况。

     1 //STATUS:C++_AC_0MS_324KB
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string.h>
     5 #include<math.h>
     6 #include<iostream>
     7 #include<string>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<queue>
    11 #include<stack>
    12 #include<map>
    13 using namespace std;
    14 #define LL __int64
    15 #define pii pair<int,int>
    16 #define Max(a,b) ((a)>(b)?(a):(b))
    17 #define Min(a,b) ((a)<(b)?(a):(b))
    18 #define mem(a,b) memset(a,b,sizeof(a))
    19 #define lson l,mid,rt<<1
    20 #define rson mid+1,r,rt<<1|1
    21 const int N=11,INF=0x3f3f3f3f,MOD=10000,STA=8000010;
    22 const double DNF=1e13;
    23 
    24 char s[N][22];
    25 int f[2][1<<N][11],len[N],g[N][N],next[2][1<<N],cnt[2],vis[1<<N];
    26 int T,n;
    27 
    28 void getg()
    29 {
    30     int i,j,k,p;
    31     for(i=0;i<n;i++){
    32         for(j=0;j<n;j++){
    33             for(k=0;k<=len[i];k++){
    34                 for(p=k;p<len[i] && p-k<len[j];p++)
    35                     if(s[i][p]!=s[j][p-k])break;
    36                 if(p==len[i] || p-k==len[j]){
    37                     g[i][j]=Min(len[i]-k,len[j]);
    38                     break;
    39                 }
    40             }
    41         }
    42     }
    43 }
    44 
    45 int main()
    46 {
    47   //  freopen("in.txt","r",stdin);
    48     int i,j,p,st1,k,r,st2,ans,rt;
    49     scanf("%d",&T);
    50     while(T--)
    51     {
    52         scanf("%d",&n);
    53         for(i=0;i<n;i++){
    54             scanf("%s",s[i]);
    55             len[i]=strlen(s[i]);
    56         }
    57         getg();
    58 
    59         mem(cnt,0);
    60         mem(vis,0);
    61         for(i=0;i<n;i++){
    62             next[0][cnt[0]]=1<<i;
    63             f[0][1<<i][i]=len[i];
    64             cnt[0]++;
    65         }
    66         mem(f[p=1],INF);
    67         for(i=1;i<n;i++){
    68             for(k=0;k<cnt[!p];k++){
    69                 st1=next[!p][k];
    70                 for(r=0;r<n;r++){
    71                     if(st1&(1<<r)){
    72                         for(j=0;j<n;j++){
    73                             if(st1&(1<<j))continue;
    74                             st2=st1|(1<<j);
    75                             if(!vis[st2]){
    76                                 vis[st2]=1;
    77                                 next[p][cnt[p]++]=st2;
    78                             }
    79                             if(g[r][j]==len[j])rt=r;
    80                             else rt=j;
    81                             f[p][st2][rt]=Min(f[p][st2][rt],f[!p][st1][r]+len[j]-g[r][j]);
    82                         }
    83                     }
    84                 }
    85             }
    86             mem(vis,0);
    87             cnt[p=!p]=0;
    88             mem(f[p],INF);
    89         }
    90 
    91         ans=INF;
    92         k=(1<<n)-1;
    93         for(i=0;i<n;i++)
    94             ans=Min(ans,f[!p][k][i]);
    95         printf("%d\n",ans);
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    spring+hibernate常见异常集合
    Java报错原因汇总
    java常见异常集锦
    连接池 druid(阿里巴巴的框架)
    企业支付宝账号开发接口实现
    Maven使用常见问题整理
    MySQL的分页
    Struts2中通配符的使用
    Centos下安装mysql 总结
    将linux用在开发环境中
  • 原文地址:https://www.cnblogs.com/zhsl/p/3011532.html
Copyright © 2011-2022 走看看