zoukankan      html  css  js  c++  java
  • ZOJ 2702 Unrhymable Rhymes(DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1702

    题目大意:给定有很多数字组成的诗,譬如 “AABB”, “ABAB”, “ABBA” and “AAAA”形式的诗句是押韵的。从中挑选,求最多可以构成多少押韵句,并且输出这些句子在原序列中的位置。

    Sample Input

    15
    1 2 3 1 2 1 2 3 3 2 1 1 3 2 2
    
    3
    1 2 3

    Sample Output

    3
    1 2 4 5
    7 8 9 10
    11 12 14 15
    
    0

    分析:设dp[i]表示从 1 到 i 之间押韵句的最大数目,f(i,j)表示当[i,j]之间可以组出一句押韵句时为1,否则为0

        则dp[i] = max{dp[i-1] , dp[j] + f(j+1,i)}

        当(i,j)之间有2个数出现的次数大于等于2时,f(i,j)=1,这2个数可以相等,即1个数出现4次

        路径打印课真是乱啊

    代码如下:

      

     1 # include<iostream>
     2 # include<cstdio>
     3 # include<vector>
     4 # include<algorithm>
     5 using namespace std;
     6 const int N = 4005;
     7 int data[N],ks[N];
     8 int n,kn;
     9 int dp[N];
    10 vector<int> path[N];    //记录路径
    11 vector<int> pos[N];
    12 int par[N];     //路径压缩
    13 int out[N/4];   //输出路径
    14 
    15 void solve()
    16 {
    17     if(n < 4)
    18     {
    19         printf("0
    
    ");
    20         return ;
    21     }
    22     kn = n;
    23     sort(ks,ks+kn);     //原序列复制后排序
    24     kn = unique(ks,ks+kn) - ks;     //去重函数,返回相邻不重复的个数,即元素种类数
    25     int i,j,k;
    26     for(i=0; i<n; i++)
    27     {
    28         data[i] = lower_bound(ks,ks+kn,data[i]) - ks;
    29         //lower_bound()返回一个 iterator 它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个大于等于value 的值。
    30     }
    31     for(i=0; i<=3; i++)
    32     {
    33         dp[i] = 0;
    34         par[i] = -1;
    35     }
    36     vector<int >tmp;
    37     for(i=3; i<n; i++)
    38     {
    39         dp[i+1] = dp[i];
    40         path[i+1] = path[i];
    41         par[i+1] = par[i];
    42         for(j=0; j<kn; j++)
    43             pos[j].clear();
    44         tmp.clear();
    45         for(j=i; j>=0; j--)
    46         {
    47             k = data[j];
    48             pos[k].push_back(j+1);
    49             if(pos[k].size()==2)
    50             {
    51                 tmp.push_back(pos[k][0]);
    52                 tmp.push_back(pos[k][1]);
    53                 pos[k].clear();
    54                 if(tmp.size()==4) break;
    55             }
    56         }
    57         if(j >= 0)
    58         {
    59             if(dp[i+1] < dp[j]+1)
    60             {
    61                 dp[i+1] = dp[j] + 1;
    62                 sort(tmp.begin(),tmp.end());
    63                 path[i+1] = tmp;    //同为vector类型,可赋值
    64                 par[i+1] = j;
    65             }
    66         }
    67     }
    68     printf("%d
    ",dp[n]);
    69     int u;
    70     u =n;
    71     for(i=dp[n]-1; i>=0; i--)
    72     {
    73         out[i] = u;
    74         u= par[u];
    75     }
    76     for(i=0; i<dp[n]; i++)
    77     {
    78         for(j=0; j<3; j++)
    79         {
    80             printf("%d ",path[out[i]][j]);
    81         }
    82         printf("%d
    ",path[out[i]][j]);
    83     }
    84     puts("");
    85 }
    86 
    87 int main()
    88 {
    89     while(scanf("%d",&n)!=EOF)
    90     {
    91         for(int i =0; i<n; i++)
    92         {
    93             scanf("%d",&data[i]);
    94             ks[i] = data[i];
    95         }
    96         solve();
    97     }
    98     return 0;
    99 }
  • 相关阅读:
    数组
    JavaScript语法
    Math.random()
    第二第三周暑期集训总结
    第一周
    ACM课程学习总结
    专题四---总结
    专题四--1004
    专题四--1005
    专题四--1006
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/3330319.html
Copyright © 2011-2022 走看看