HDU 4455 Substrings (2012年杭州賽區現場賽C題)

來源:互聯網
上載者:User

標籤:dp   找規律   

1.題目描述:點擊開啟連結

2.解題思路:本題利用dp解決。不過這個dp的思路的確比太容易想到。需要觀察規律才能發現。我們可以從貢獻值的角度考慮。以題目中給的範例來說明這種方法。

通過觀察相鄰兩個w值,我們會發現一個事實:每個大區間都包含了小區間的解(這裡的解即原題中的sum值)。但是這還不夠,觀察圖上標記為紅色的數字,它們可以看做是上一個w值對應的區間多出來的新數字,如果我們可以算出這些紅色數位貢獻值,那麼我們就能得到當前w下的解。那麼該如何計算呢?


繼續觀察後會發現,每次w增加1,區間個數就會減少1個,也就是說,w-1時候的最後一個區間的結果要被減掉,才是w-1的解對當前w的貢獻。接下來看紅色數位貢獻,由於當前區間長度為w,那麼某個數字i和前一個i的距離差<w時,這些數字都不能算入。比如以w=5的情況為例,w=5時候,第一個紅色數字4要被算入,因為它和前一個4(如果不存在前一個數就看做在0位置,數組的起始下標從1開始)距離為5,不滿足距離<w,因此要被算入,而第二個紅色數字4和前一個4距離為1,滿足1<w的要求,因此不能被算入。也就是說,我們需要知道數位距離分別有幾個,比如距離為x的有dis[x]個,那麼w-1時候的紅色數位貢獻值假設為sum,那麼w時候,紅色數位貢獻就是sum-dis[w-1]。同時,我們用last[i]表示最後i個數字有幾種不同的數字。於是得到如下的遞推式:

dp(w)=dp(w-1)-last(w-1)+(sum-dis[w-1]);

上式中的sum是w-1時候紅色數字對答案的貢獻。當w=0時候,sum=n。這樣就可以用O(1)時間得到所有的dp(w)了。當然,根據上述分析,我們需要提前預先處理出來dis[i]和last[i],詳細過程見代碼。

本題最終的時間複雜度是O(N+Q)。

3.代碼:

#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<algorithm>#include<cassert>#include<string>#include<sstream>#include<set>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<cctype>#include<functional>using namespace std;#define me(s) memset(s,0,sizeof(s))#define rep(i,n) for(int i=0;i<(n);i++)#define pb push_backtypedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;typedef pair <int, int> P;const int N = 1000010;int a[N], dis[N], vis[N], last[N], sum;ll dp[N];int n;int main(){while (~scanf("%d", &n) && n){sum = n; //sum是前一個w值中紅色數字對答案的貢獻值me(vis); me(dis);for (int i = 1; i <= n; i++){scanf("%d", &a[i]);dis[i - vis[a[i]]]++; //統計不同距離的個數vis[a[i]] = i;//更新a[i]上一次出現的位置}me(vis);last[1] = 1;//last[i]表示最後i個數中有幾個不同的數vis[a[n]] = 1;//標記a[n]訪問過for (int i = 2; i <= n; i++)if (!vis[a[n - i + 1]])//發現新的沒有出現過的數,last[i]++{vis[a[n - i + 1]]++;last[i] = last[i - 1] + 1;}else last[i] = last[i - 1];dp[1] = n;for (int i = 2; i <= n; i++){sum -= dis[i - 1];//更新sum,得到當前w時候紅色數字對答案的貢獻值dp[i] = dp[i - 1] - last[i - 1] + sum; }int q;scanf("%d", &q);for (int i = 0; i<q; i++){int w;scanf("%d", &w);printf("%I64d\n", dp[w]);}}}


著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

HDU 4455 Substrings (2012年杭州賽區現場賽C題)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.