UVALive 3716 DNA Regions ——(式子变形)

  一开始直接想到了二分,写了一发然后过了全部样例就交了,果断WA。因为这个问题显然是不满足单调性的。

  然后想之前刚做的斜率优化DP,但是那个是求斜率最大值,不是求满足斜率大于一定值的最大长度的。也构造不出好的方法。

  最后的方法是列个式子:i+1~j位置可以成立仅当 (pre[j] - pre[i]) / (j - i) >= (100-p) / 100。不妨把p变成100-p,再作化简得:

  100 * pre[j] - p * j >= 100 * pre[i] - p * i。因此,不妨令val[i] = 100 * pre[i] - p * i。那么以val作为关键字进行排序,只要某个位置序号大于前面的,那么这一段显然就是可以的了。因此,只要线性的扫一遍更新最大值即可。

  代码如下:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 using namespace std;
 5 const int N = 150000 + 5;
 6 
 7 char s1[N], s2[N];
 8 int n,p;
 9 int pre[N];
10 struct node
11 {
12     int val, id;
13     bool operator < (const node & temp) const
14     {
15         return val == temp.val ? id < temp.id : val < temp.val;
16     }
17 }my[N];
18 
19 int main()
20 {
21     while(scanf("%d%d",&n,&p) == 2)
22     {
23         if(n == 0 && p == 0) break;
24         scanf("%s%s",s1+1,s2+1);
25         
26         p = 100 - p;
27         for(int i=1;i<=n;i++) pre[i] = pre[i-1] + (s1[i] == s2[i]);
28         for(int i=0;i<=n;i++) my[i].val = 100 * pre[i] - p * i, my[i].id = i;
29         sort(my, my+1+n);
30         int minn = my[0].id;
31         int ans = 0;
32         for(int i=1;i<=n;i++)
33         {
34             if(my[i].id < minn)
35             {
36                 minn = my[i].id;
37             }
38             else ans = max(ans, my[i].id - minn);
39         }
40         if(ans != 0) printf("%d
",ans);
41         else puts("No solution.");
42     }
43     return 0;
44 }
原文地址:https://www.cnblogs.com/zzyDS/p/6730916.html