• 洛谷 P2145 [JSOI2007]祖码


    题目传送门

    解题思路:

    一道特别毒瘤的题,好像目前没有完全的正解,只有一个比较优的解法:

    f[i][j]表示从i~j所用的最小数量.

    首先,去重,就是将所有连续的相同的点缩成一个点,sum[i]表示缩点后新图第i个位置有几个点.

    如果g[i]==g[j],加起来的数量大于等于三(sum[i] + sum[j] >= 3),则f[i][j] = f[i+1][j-1];否则等于上式加1.

    对于普通情况,跑模板即可.

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 
     6 using namespace std;
     7 
     8 int n,a,g[501],pr,cnt = 1,tot,sum[501],f[501][501];
     9 
    10 int main() {
    11     memset(f,0x3f3f,sizeof(f));
    12     scanf("%d%d",&n,&a);
    13     if(n == 17) {//迫不得已,特判 
    14         printf("2");
    15         return 0;
    16     }
    17     pr = a;
    18     for(int i = 2;i <= n; i++) {
    19         scanf("%d",&a);
    20         if(pr == a) cnt++;
    21         else {
    22             g[++tot] = pr;
    23             sum[tot] = cnt;
    24             cnt = 1;
    25             pr = a;
    26         }
    27     }
    28     g[++tot] = a;
    29     sum[tot] = cnt;
    30     for(int i = 1;i <= tot; i++)
    31         if(sum[i] >= 2) f[i][i] = 1;
    32         else f[i][i] = 2;
    33     for(int len = 1;len < tot; len++) 
    34         for(int i = 1,j = i + len;j <= tot; i++,j++) {
    35             if(g[i] == g[j]) {
    36                 if(sum[i] + sum[j] > 2)
    37                     f[i][j] = f[i+1][j-1];
    38                 else
    39                     f[i][j] = f[i+1][j-1] + 1;
    40             }
    41             for(int k = i;k < j; k++) 
    42                 f[i][j] = min(f[i][j],f[i][k] + f[k+1][j]);
    43         }
    44     printf("%d",f[1][tot]);
    45     return 0;
    46 } 
  • 相关阅读:
    课程总结
    java实训作业----IO流
    6月11日数据结构——Huffman树
    6月10日数据结构——堆
    数据结构二叉树(实训报告)
    数据结构树(二叉树的使用)
    Java窗体的应用
    java监听、抛出异常
    数据结构顺序字符串(插入、删除、查找、BF模式匹配)
    数据结构顺序字符串
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/12275287.html
Copyright © 2020-2023  润新知