算法學習——決策單調性優化DP

update in 2019.1.21 優化了一下文中年代久遠的代碼 的格式……

?

什么是決策單調性?

在滿足決策單調性的情況下,通常決策點會形如1111112222224444445555588888.....

即不可能會出現后面點的決策點小于前面點的決策點這種情況。

那么這個性質應該如何使用呢?

 1,二分。

  考慮到決策點單調遞增,因此我們考慮用單調隊列存下當前的決策選取情況。

  單調隊列中存的量會帶3個信息:這是哪個決策點,這個決策點會給哪個區間的點產生貢獻(這是一個區間,所以算2個信息)

  相當于隊列中存了很多個區間,假設當前的決策點是這樣的:1111112222222333333,

  現在插入4這個決策,那么我們就是要找到最靠左的合法位置將決策序列變為類似這樣的序列:111111222222444444444,

  因為決策單調,所以要覆蓋肯定是一整段一整段的覆蓋,因此我們先判斷4是否可以覆蓋完3這個區間,只需要看3的左端點是否可以被替換即可。

  我們重復覆蓋整個區間這個操作,直到有個區間無法被完整覆蓋,或者已經到了不合法的位置(因為第x個點只能給區間[x + 1, n]內的點產生貢獻)。

  如果這個區間無法被完整覆蓋,那么我們就在這個區間內二分找到最靠左的點使得4可以替換掉這個區間內的數,然后修改管理這個區間的數的區間,把被覆蓋的區間讓給4.

  每次操作前彈掉已經沒有用的決策點,于是可以實現O(1)轉移。(例如當前隊首的決策點可以更新[3, x-1]這個區間,但我們已經枚舉到x了,所以這個決策點顯然就沒有什么用了)  

  以下是某個年代久遠的一道決策單調性優化的代碼。

?

 1 /*[NOI2009]詩人小G by ww3113306*/
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 #define R register int
 5 #define AC 100100
 6 #define LL long long
 7 #define LD long double
 8 #define ac 101000
 9 #define inf 1000000000000000000LL
10 int t, L, p, n;
11 int Next[AC], s[AC], last[AC], l[AC], r[AC];//對應決策的管理區間,Next對last進行相反操作,以便輸出
12 int q[AC], head, tail;//存下當前是哪個決策
13 LD f[AC];
14 LL sum[AC];
15 char ss[ac][45];
16 
17 inline LD qpow(LD x)//error!!!x也要用LD!!!
18 {
19     LD ans = 1;int have = p;
20     while(have)
21     {
22         if(have & 1) ans *= x;
23         x *= x, have >>= 1;
24     }
25     return ans;
26 }
27 
28 inline LD count(int x, int j){return f[j] + qpow(abs(sum[x] - sum[j] - L - 1));}//j --- > x
29 
30 inline void pre()
31 {
32     scanf("%d%d%d", &n, &L, &p);
33     for(R i = 1; i <= n; i ++)
34     {
35         scanf("%s", ss[i] + 1);
36         s[i] = strlen(ss[i] + 1) + 1;//加上后面的空格
37         sum[i] = sum[i-1] + s[i];//求出前綴和
38     }    
39 }
40 
41 void half(int x)//二分查找
42 {
43     int now = q[tail], ll = max(l[now], x + 1), rr = n, mid;//因為可能可以覆蓋多個區間
44     while(ll < rr)
45     {
46         mid = (ll + rr) >> 1;
47         if(count(mid, x) < count(mid, now)) rr = mid;//如果更優就往左縮短
48         else ll = mid + 1;//不然就向右尋找
49     }
50     r[q[tail]] = ll - 1;
51     q[++tail] = x, l[x] = ll, r[x] = n;
52 }
53 
54 inline void getans()
55 {
56     head = 1, tail = 1, q[1] = 0, l[0] = 1, r[0] = n;
57     for(R i = 1; i <= n; i ++)
58     {
59         while(r[q[head]] < i) ++head;//如果當前隊首已經取不到了
60         int now = q[head];
61         f[i] = count(i, now);//error ??? 用函數的話會爆了會自動轉換為inf?
62         last[i] = now;
63         if(count(n, q[tail]) < count(n, i)) continue;//如果最后一個都不夠優,那就不二分了
64         while(count(l[q[tail]], q[tail]) > count(l[q[tail]], i)) --tail;//如果當前可以覆蓋前面的整個區間
65         half(i);//注意上面的while要在調用half之前修改,這樣取到的now才是正確的
66     }
67 }
68 
69 inline void write()
70 {
71     if(f[n] > inf) puts("Too hard to arrange");
72     else
73     {
74         printf("%lld\n", (LL)(f[n] + 0.5));//注意精度誤差
75         for(R i = n; i; i = last[i]) Next[last[i]] = i;
76         int now = 0;
77         for(R i = 1; i <= n; i ++)
78         {
79             now = Next[now];//now先跳了吧
80             int be = now;//先只到這行結尾,因為for還要加的
81             for(R j = i; j < be; j ++) printf("%s ", ss[j] + 1);
82             printf("%s\n", ss[be] + 1), i = be;//最后再賦i,因為for中還要用到當前i
83         }
84     }
85     puts("--------------------");
86 }
87 
88 int main()
89 {
90     scanf("%d", &t);
91     while(t--) pre(), getans(), write();
92     return 0;
93 }
View Code

?

 2,分治

  假設我們當前的被決策區間是[l, r], 決策點區間是[ll, rr],那么我們取被決策區間的中點mid = (l + r) >> 1,然后在[ll, rr]中暴力尋找mid的最優決策點k,于是根據決策單調性,我們有:

  被決策區間[l, mid - 1]對應的決策點區間是[ll, k].同理,被決策區間[mid + 1, r]對應的決策點區間是[k, rr],于是我們就將這個區間劃分為了2半,不斷向下遞歸減小決策點范圍即可用正確的復雜度求出所有的轉移。

?

轉載于:https://www.cnblogs.com/ww3113306/p/9889295.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249104.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249104.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249104.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SVG畫一個箭頭

參考菜鳥手冊&#xff1a; https://www.runoob.com/svg/svg-tutorial.html 打開菜鳥中的在線工具 在可視化截圖拖拉元素繪制箭頭 點擊command U 查看源碼 將源碼拷入html代碼中&#xff0c;查看效果 最后&#xff0c;貼出源碼供大家參考 <!DOCTYPE html> <…

HP Instant Information

HP Instant Information before HP-UX 11i v3 《管理系統和工作組&#xff1a;HP-UX系統管理員指南》 After HP-UX 11i v3 《HP-UX系統管理指南》(由多個文檔組成的文檔集) 《HP-UX系統管理員指南&#xff1a;概述》 《HP-UX系統管理員指南&#xff1a;配置管理》 《HP-UX系統管…

CodeForces 258D Little Elephant and Broken Sorting(期望)

CF258D Little Elephant and Broken Sorting 題意 題意翻譯 有一個\(1\sim n\)的排列&#xff0c;會進行\(m\)次操作&#xff0c;操作為交換\(a,b\)。每次操作都有\(50\%\)的概率進行。 求進行\(m\)次操作以后的期望逆序對個數。 \(n,m\le 1000\) 輸入輸出格式 輸入格式&#x…

記一次vue項目yarn打包環境配置失效的解決方案

項目中使用到了yarn打包工程&#xff0c;主要有以下幾個命名。 # build for production with minification yarn run build# build for production and view the bundle analyzer report yarn run build --report# 自定義API地址 baseurl"http://127.0.0.1:8080/api/&quo…

數字簽名與HTTPS詳解

因為HTTP協議本身存在著明文傳輸、不能很好的驗證通信方的身份和無法驗證報文的完整性等一些安全方面的確點&#xff0c;所以才有了HTTPS的缺陷。HTTPS確切的的說不是一種協議&#xff0c;而是HTTP SSL (TSL)的結合體。HTTP報文經過SSL層加密后交付給TCP層進行傳輸。SSL(安全套…

[BZOJ4320][ShangHai2006]Homework(根號分治+并查集)

對于<sqrt(300000)的詢問&#xff0c;對每個模數直接記錄結果&#xff0c;每次加入新數時暴力更新每個模數的結果。 對于>sqrt(300000)的詢問&#xff0c;枚舉倍數&#xff0c;每次查詢大于等于這個倍數的最小數是多少&#xff0c;這個操作通過將詢問逆序使用并查集支持。…

VScode 結局插件prettier和vetur格式化沖突

先上配置代碼 {"workbench.iconTheme": "vscode-icons","workbench.startupEditor": "newUntitledFile","workbench.colorTheme": "One Dark Pro","editor.fontSize": 14,"editor.tabSize":…

WPF效果(GIS三維續篇)

去年這個時候簡單的摸索了一下三維的GIS相關的東西,也就是僅僅玩耍了一把,這次來點真正用的上的干貨效果效果&#xff1a; 1、加載自定義百度樣式的瓦片效果 2、加載自定義百度樣式的縮放效果 3、快速手動進去咱的大帝都 4、加載海量Mark效果 5、加載海量Mark和簡單模型效果 6、…

vue 表單 驗證 async-validator

1、使用插件async-validator async-validator 地址&#xff1a;https://github.com/yiminghe/async-validator 2、示例&#xff08;vueelement-ui&#xff09; <el-form :model"numberValidateForm" ref"numberValidateForm" label-width"100px&qu…

[19/04/23-星期二] GOF23_創建型模式(工廠模式、抽象工廠模式)

一、工廠模式(分為&#xff1a;簡單工廠模式、工廠方法模式、抽象工廠模式) 實現了創建者和調用者的分離 核心本質&#xff1a;1、實例化對象&#xff0c;用工廠方法代替new操作&#xff1b;2、將選擇實現類、創建對象統一管理和控制&#xff0c;從而將調用者跟實現類解耦。 簡…

Chrome瀏覽器12px問題-webkit-text-size-adjust: none 已失效的解決方案

對于早期的chrome, 如果要想顯示12px以下的字體&#xff0c;一般通用的方案都是在對應的元素中添加 div {-webkit-text-size-adjust: none; }但是我今天遇到的需求&#xff0c;添加了之后沒有反應&#xff0c;而且瀏覽就根本不支持這種寫法。 在網上看到了博客《Chrome瀏覽器…

CSRFGuard工具介紹

理解CSRFGuard的基礎&#xff1a;http://www.runoob.com/jsp/jsp-tutorial.html 1&#xff1a;您需要做的第一件事是將OWASP.CSRFARGAD.JAR庫復制到類路徑中。放置Owasp.CsrfGuard.jar最常見的類路徑位置在Web應用程序的WEB-INF文件夾的lib目錄中。 OWASP CSRFGARD 3在傳統Java…

[19/04/24-星期三] GOF23_創建型模式(建造者模式、原型模式)

一、建造者模式 本質&#xff1a;分離了對象子組件的單獨構造(由Builder負責)和裝配的分離(由Director負責)&#xff0c;從而可以構建出復雜的對象&#xff0c;這個模式適用于&#xff1a;某個對象的構建過程十分復雜 好處&#xff1a;由于構建和裝配的解耦&#xff0c;不同的構…

深入理解vue中的slot與slot-scope

寫在前面 vue中關于插槽的文檔說明很短&#xff0c;語言又寫的很凝練&#xff0c;再加上其和methods&#xff0c;data&#xff0c;computed等常用選項在使用頻率、使用先后上的差別&#xff0c;這就有可能造成初次接觸插槽的開發者容易產生“算了吧&#xff0c;回頭再學&#…

js 轉義

1. JavaScript 特殊字符 2. 正反斜杠互相替換 a/b/c.replace(/\//g,\\) // "a\b\c" $0.value.replace(/\\/g,\/) // a/b/c 獲取到 而不提取出 某個值后進行直接處理 \ 有轉義功能&#xff0c;所以一旦解析必然轉義&#xff0c;通常是直接獲取到數據源…

關于Java抽象類,接口與實現接口及派生類繼承基類

1. 抽象類 抽象類就是有一個或多個方法只被聲明而未被實現。 抽象方法的聲明以分號結束&#xff0c;并且用關鍵字abstract來說明它以標識它為抽象方法。 格式&#xff1a; public abstract class 類名{ 定義變量// 抽象方法// } 2. 接口是抽象類的一種&#xff0c;之包含常量…

ie兼容響應式布局的實現總結

雖然說響應式設計的理想狀態是&#xff0c;需對pc/移動各種終端進行響應&#xff1b;但是現實是高分辨率的pc端與手機終端屏幕相差太大&#xff0c;像電商這樣有大量圖片和文字 信息的同時排版要求精準的頁面&#xff0c;設計一個同時適應高分辨率pc又適合小尺寸的手機終端是挑…

Luogu P1471 方差

題目傳送門 開了十倍空間才過是什么鬼&#xff1f;該不會我線段樹炸了吧……細思極恐 平均數都會求&#xff0c;維護區間和&#xff0c;到時候除一下就好了。 方差的求法如下(用的Luogu的圖片) 因為要維護一個平方&#xff0c;我們可以考慮使用van♂完全平方公式將它拆開&#…

python學習day17 遞歸函數

遞歸函數 http://www.cnblogs.com/Eva-J/articles/7205734.html def age(n):if n 4:return 40elif n >0 and n < 4:return age(n1) 2print(age(1)) # 46 只要寫遞歸函數&#xff0c;必須要有結束條件。 二分法查找 l [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,5…

2018年最好用的20個Bootstrap網站模板

Bootstrap是目前最受歡迎也是最簡潔的建站方式之一&#xff0c;尤其是伴隨移動端的發展&#xff0c;響應式設計已經毫無疑問成為了網頁設計的趨勢&#xff0c;網站建設要求兼容手機端已經是一種剛需&#xff0c;也成為提升用戶體驗的一種必要方式。但這無疑會加大設計師和前端人…