1. 程式人生 > >UVa 1451 Average 解題報告(斜率優化)

UVa 1451 Average 解題報告(斜率優化)

1451 - Average

Time limit: 3.000 seconds

A DNA sequence consists of four letters, A, C, G, and T. The GC-ratio of a DNA sequence is the number of Cs and Gs of the sequence divided by the length of the sequence. GC-ratio is important in gene finding because DNA sequences with relatively high GC-ratios might be good candidates for the starting parts of genes. Given a very long DNA sequence, researchers are usually interested in locating a subsequence whose GC-ratio is maximum over all subsequences of the sequence. Since short subsequences with high GC-ratios are sometimes meaningless in gene finding, a length lower bound is given to ensure that a long subsequence with high GC-ratio could be found. If, in a DNA sequence, a 0 is assigned to every A and T and a 1 to every C and G, the DNA sequence is transformed into a binary sequence of the same length. GC-ratios in the DNA sequence are now equivalent to averages in the binary sequence.

Position 1 1 1 1 1 1 1 1
Index 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
Sequence 0 0 1 0 1 0 1 1 0 1 1 0 1 1 0 1 0


For the binary sequence above, if the length lower bound is 7, the maximum average is 6/8 which happens in the subsequence [7,14]. Its length is 8, which is greater than the length lower bound 7. If the length lower bound is 5, then the subsequence [7,11] gives the maximum average 4/5. The length is 5 which is equal to the length lower bound. For the subsequence [7,11], 7 is its starting index and 11 is its ending index.

Given a binary sequence and a length lower bound L, write a program to find a subsequence of the binary sequence whose length is at least L and whose average is maximum over all subsequences of the binary sequence. If two or more subsequences have the maximum average, then find the shortest one; and if two or more shortest subsequences with the maximum average exist, then find the one with the smallest starting index.

Input 

Your program is to read from standard input. The input consists of T test cases. The number of test cases T is given in the first line of the input. Each test case starts with a line containing two integers n (1$ \le$n$ \le$100, 000) and L (1$ \le$L$ \le$1, 000) which are the length of a binary sequence and a length lower bound, respectively. In the next line, a string, binary sequence, of length n is given.

Your program is to write to standard output. Print the starting and ending index of the subsequence.

The following shows sample input and output for two test cases.

2 
17 5 
00101011011011010 
20 4 
11100111100111110000
7 11 
6 9

    解題報告: 斜率優化裸題。一直聽說過斜率優化這個概念,但是沒有具體的學過,今天也是看論文和程式碼才瞭解了。

    詳細的看一遍論文,然後對照著程式碼看就好了。程式碼如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
using namespace std;

#define ff(i, n) for(int i=0;i<(n);i++)
#define fff(i, n, m) for(int i=(n);i<=(m);i++)
#define dff(i, n, m) for(int i=(n);i>=(m);i--)
#define mem(a) memset((a), 0, sizeof(a))
typedef long long LL;
typedef unsigned long long ULL;
void work();

int main()
{
#ifdef ACM
    freopen("in.txt", "r", stdin);
//    freopen("in.txt", "w", stdout);
#endif // ACM

    work();
}

/*****************************************/

const int maxn = 111111;
int  sum[maxn];
int  que[maxn];
char str[maxn];

double getK(int a, int b)
{
    return (sum[b]-sum[a]+0.0)/(b-a);
}

void work()
{
    int T;
    scanf("%d", &T);
    fff(cas, 1, T)
    {
        int n, l;
        scanf("%d%d%s", &n, &l, str+1);

        fff(i, 1, n)
            sum[i] = sum[i-1]+(str[i]-'0');

        int len = l;
        double ans = getK(0, l);
        int sta = 0, end = l;

        int top = -1, bot = 0;
        fff(i, l, n)
        {
            int last = i - l;
            while(bot < top && getK(que[top], last) <= getK(que[top-1], que[top]))
                top--;
            que[++top] = last;

            while(bot < top && getK(que[bot], i) <= getK(que[bot+1], i))
                bot++;
            double k = getK(que[bot], i);
            if(ans < k || (ans == k && len > i - que[bot]))
            {
                ans = k;
                sta = que[bot];
                end = i;
                len = i - que[bot];
            }
        }

        printf("%d %d\n", sta + 1, end);
    }
}


相關推薦

UVa 1451 Average 解題報告斜率優化

1451 - Average Time limit: 3.000 seconds A DNA sequence consists of four letters, A, C, G, and T. The GC-ratio of a DNA sequence is the

BZOJ-1010-[HNOI2008]玩具裝箱toy斜率優化

-s 要去 sca sigma open closed splay 填充物 hide Description   P教授要去看奧運,但是他舍不下他的玩具,於是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮,其可以將任意物品變成一堆,再放到一種特殊的一維容器中。P教

【Bsoj2684】鋸木廠選址斜率優化

任務 post def sin solution name line () des Description 從山頂上到山底下沿著一條直線種植了n棵老樹。當地的政府決定把他們砍下來。為了不浪費任何一棵木材,樹被砍倒後要運送到鋸木廠。木材只能按照一個方向運輸:朝山下運。山腳下有

1010: [HNOI2008]玩具裝箱toy斜率優化

教授 最小 sta 長度 輸入 常量 limit ... col 1010: [HNOI2008]玩具裝箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 12280 Solved: 5277[Submit][St

3156: 防禦準備斜率優化

return getchar() == div lan 前綴 php 查點 準備 鏈接 思路   斜率優化。   f[i] 表示i點建檢查點的花費。   f[i] = f[j] + i*(i-j-1)-(s[i-1]-s[j]) + a[i],從j轉移,s為前綴和

洛谷P3628 [APIO2010]特別行動隊斜率優化

new open 同類項 freopen -- www. pro ios check 傳送門 先寫出轉移方程$$dp[i]=max\{dp[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c\}$$ 假設$j$比$k$更優,則有$

洛谷P4072 [SDOI2016]征途斜率優化

傳送門 tps double nbsp ble esp 就是 int turn 傳送門 推式子(快哭了……)$$s^2*m^2=\sum _{i=1}^m (x_i-\bar{x})^2$$ $$s^2*m^2=m*\sum _{i=1

[TJOI2017] DNA 解題報告 hash+二分

log h+ get www. signed targe 相差 ria type 題目鏈接:https://www.luogu.org/problemnew/show/P3763 題目大意: 給定原串S0,詢問S0有多少個子串和給定串S相差不到3個字母 題解: 我們

Codeforces 514C. Watto and Mechanism解題報告字典樹

test names cin 單詞 turn void can include 傳送門 傳送門 題意:給你一個字典和一些詢問,問你對於每個詢問的字符串必須更改一個字符,能否得到字典中的某一個單詞。 思路:先構造一顆字典樹,然後搜一遍就行了,要註意strlen不能每次都用,常

[JZOJ 5906] [NOIP2018模擬10.15] 傳送門 解題報告樹形DP

nor dos color 樹形dp getchar() 傳送門 noip 轉化 每一個 題目鏈接: https://jzoj.net/senior/#contest/show/2528/2 題目: 8102年,Normalgod在GLaDOS的幫助下,研制出了傳

[jzoj 5178] [NOIP2017提高組模擬6.28] So many prefix? 解題報告KMP+DP

題目連結: https://jzoj.net/senior/#main/show/5178 題目: 題解: 我們定義$f[pos]$表示以位置pos為字尾的字串對答案的貢獻,答案就是$\sum_{i=1}^{n} f[i]$ 考慮怎麼得到f陣列,我們有$f[i]=f[nxt[i]]+[i是偶數]

hdu1258---Sum It Up解題報告DFS入門

                                         &n

[JZOJ 5912] [NOIP2018模擬10.18] VanUSee 解題報告 KMP+博弈

題目連結: https://jzoj.net/senior/#contest/show/2530/2 題目:   眾所周知,cqf童鞋對哲學有著深入的理解和認識,並常常將哲學思想應用在實際生活中,例如鍛鍊摔角技術或者研究化(fa)學。  由於cqf童鞋哲學造詣太過高深,以至

[JZOJ 5852] [NOIP2018提高組模擬9.6] 相交 解題報告 倍增+LCA

題目連結: http://172.16.0.132/senior/#main/show/5852 題目: 題目大意: 多組詢問,每次詢問樹上兩條鏈是否相交 題解: 兩條鏈相交併且僅當某一條鏈的兩個端點的LCA在另一個端點上 對於每次詢問,我們分別處理出兩條鏈端點的LCA,通過倍增判斷是否存在

洛谷4983 忘情WQS二分斜率優化

題目 程式碼 WQS二分+斜率優化 公式簡化看這https://www.luogu.org/blog/xnzy1314/wang-qing-ti-xie-post 其他就很套路了,只要在f轉移時

POJ 2406 Power Strings 解題報告雜湊

Power Strings Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 32810 Accepted: 13670 Description Given two strings a and b

洛谷3571 POI2014 SUP-Supercomputer 斜率優化

一道神仙好題。 首先看到有多組\(k\),第一反應就是離線。 考慮貪心。 我們每次一定是儘量選擇有兒子的節點。以便於我們下一次擴充套件。 但是對於一個\(k\),每次貪心的複雜度是\(O(n)\) 總複雜度是\(O(nq)\),肯定過不了。 qwq 那我們只能來考慮一個快速求一個\(k\)的答案。 感

HDU 3507 Print Article斜率優化

顯然的斜率優化模型 但是單調佇列維護斜率單調性的時候出現了莫名的鍋orz 程式碼 #include <cstdio> #include <algorithm> #include <cstring> #include <deque> #define int

poj2502解題報告Dijskstra演算法

題目大意:在一個城市裡,分佈著若干條地鐵線路,每條地鐵線路有若干個站點,所有地鐵的速度均為40km/h。現在你知道了出發地和終點的座標,以及這些地鐵線路每個站點的座標,你的步行速度為10km/h,且你到了地鐵的任意一個站之後就剛好有地鐵出發。問你從出發點到終點最少需要多少時