Vijos P1243 生產產品 (單調隊列最佳化DP)

來源:互聯網
上載者:User

標籤:

 

 

 

題意:

  必須嚴格按順序執行M個步驟來生產一個產品,每一個步驟都可以在N台機器中的任何一台完成。機器i完成第j個步驟的時間為T[i][j]。把半成品從一台機器上搬到另一台機器上也需要一定的時間K。每台機器最多隻能連續完成產品的L個步驟。也就是說,如果有一台機器連續完成了產品的L個步驟,下一個步驟就必須換一台機器來完成。問一個產品最短需要多長時間呢?(對於100%的資料,N<=5, L<=50000,M<=100000)

 

 

題意:

  被高中生虐了~

  題意要求盡量縮短時間來完成一件產品,但是由於需要按照步驟,所以多線程的方式不必考慮。dp[i][j]=min(dp[k][p])+(sum[i][j] - sum[k][j]),dp[i][j]表示完成前i個步驟,且最後一步是在第j台機器上完成。sum[k][j]表示第j台機器完成第1~k個步驟所需要的時間和,但是k與i的距離不宜超過規定的L。式子也可以這樣寫:dp[i][j]=min(dp[k][p] -  sum[k][j])+ sum[i][j] ,那麼就單單看這項min(dp[k][p] -  sum[k][j])就行了,這不就是類似於在序列區間a[i-L]~a[i-1]之間找一個最小值的問題?那就可以用單調隊列解決了。複雜度為O(n2*m),是與L無關的。

 

 

 

 

 

 

 1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <deque> 7 #include <map> 8 #include <algorithm> 9 #include <vector>10 #include <iostream>11 #define pii pair<int,int>12 #define INF 0x3f3f3f3f13 #define LL long long14 #define ULL unsigned long long15 using namespace std;16 const double PI  = acos(-1.0);17 const int N=100100;18 const int M=10;19 int m, n, K, L;20 int t[N][M], dp[N][M];21 int que[N][M], idx[N][M], top[M], rear[M];22 23 void calmin(int i)24 {25     for(int j=1; j<=n; j++)26     {27         int tar=INF;28         for(int k=1; k<=n; k++)29         {30             if(j==k)    continue;31             tar=min(tar, dp[i][k]);32         }33         tar-=t[i][j];34         while( top[j]<rear[j] && que[rear[j]-1][j]>=tar )    rear[j]--;35         que[rear[j]][j]=tar;36         idx[rear[j]][j]=i;37         rear[j]++;38     }39 }40 41 void init()42 {43     memset(dp,0x3f,sizeof(dp));44     memset(top,0,sizeof(top));45     memset(rear,0,sizeof(rear));46     memset(dp[0],0,sizeof(dp[0]));47     memset(que,0,sizeof(que));48     memset(idx,0,sizeof(idx));49     for(int i=1; i<=n; i++) //在單個機器上運行所有任務,求區間和50         for(int j=1; j<=m; j++)51             t[j][i]+=t[j-1][i];52     for(int i=1; i<=n; i++)53         rear[i]++;54 }55 int cal()56 {57     init();58     for(int i=1; i<=m; i++) //枚舉步驟59     {60         for(int j=1; j<=n; j++) //用第j台機器來完成i項61         {62             while( top[j]<rear[j] && idx[top[j]][j]<i-L)63                 top[j]++;       //到期64             int &d=dp[i][j];65             if( top[j]==rear[j] )66             {67                 for(int k=1; k<=n; k++)68                 {69                     if(k==j)continue;70                     d=min(d, dp[i-1][k]);71                 }72                 d+=t[i][j]-t[i-1][j];73             }74             else    d=min(d, que[top[j]][j]+t[i][j]+K );75         }76         calmin(i);77     }78 79     int ans=INF;80     for(int i=1; i<=n; i++)    ans=min(ans, dp[m][i]);81     return ans-K;   //第一步不需要換機器費用82 }83 84 85 int main()86 {87     //freopen("input.txt","r",stdin);88     while(~scanf("%d%d%d%d",&m, &n, &K, &L))89     {90         for(int i=1; i<=n; i++) //機器91             for(int j=1; j<=m; j++) //步驟92                 scanf("%d",&t[j][i]);93         cout<<cal()<<endl;94     }95     return 0;96 }
AC代碼

 

Vijos P1243 生產產品 (單調隊列最佳化DP)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.