USACO 1.1 broken necklace 分析

    技术2024-11-02  28

    题目大意:

          给出一串由b,r,w组成的珠子,其中w可以当作b或r使用,可以从某一处断开,然后向两边收集,只有同色才能收集,否则停止,求最多能收集的珠子数目

    规模:

          珠子串长度<=350

    方法1:模拟

          枚举断开的位置,然后分别向两边开始收集珠子;

          效率是O(N^2)

    看了Analysis之后,学习了Dynamic Progamming的方法

    方法2:

         如果朝某一个方向开始搜集,能搜集到的珠子只和前面收集的相关,满足了无后向性。

      if color[i] = 'w' r[i] = r[i-1]+1 b[i] = b[i-1]+1 color[i] = 'r' r[i] = r[i-1]+1 b[i] = 0 color[i] = 'b' r[i] = 0 b[i] = b[i-1]+1   

     分别预处理出从左向后和从右向左两个方向的情况,再枚举间断点就可以了

         效率是O(N)

     

    这道题目最大的启发在于倍长字符串来处理需要循环的问题

     

    我的代码:

    #include <stdio.h> #include <string.h> int main(){ freopen("beads.in", "r", stdin); freopen("beads.out", "w", stdout); int n, color[1000]; memset(color, 0, sizeof(color)); scanf("%d", &n); char c; c = getchar(); int i, breakpoint; for (i = 0; i < n; i++){ c = getchar(); if (c == 'b') color[i] = 1; else if (c == 'r') color[i] = 2; color[i+n] = color[i]; } int max = 0; for (breakpoint = 0; breakpoint < n; breakpoint++){ int left = breakpoint, right = breakpoint+1; int now, collect = 0; now = 0; while (left >= 0){ if (now == 0) now = color[left]; if (now != color[left] && color[left] != 0) break; collect++; left--; } now = 0; while (right < n+n){ if (now == 0) now = color[right]; if (now != color[right] && color[right] != 0) break; collect++; right++; } if (collect > max) max = collect; } if (max > n) max = n; printf("%d/n", max); return 0; }

    最新回复(0)