https://www.vijos.org/p/1243
论文题,对每台机器都维护一个队列,进入队列总个数为O(M*N^2),总的时间复杂度也为O(M*N^2)。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <stack> #include <cctype> #include <utility> #include <map> #include <string> #include <climits> #include <set> #include <string> #include <sstream> #include <utility> #include <ctime> #include <bitset> using std::priority_queue; using std::vector; using std::swap; using std::stack; using std::sort; using std::max; using std::min; using std::pair; using std::map; using std::string; using std::cin; using std::cout; using std::set; using std::queue; using std::string; using std::stringstream; using std::make_pair; using std::getline; using std::greater; using std::endl; using std::multimap; using std::deque; using std::unique; using std::lower_bound; using std::random_shuffle; using std::bitset; using std::upper_bound; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> PAIR; typedef multimap<int, int> MMAP; typedef LL TY; typedef long double LF; const int MAXN(100010); const int MAXM(100010); const int MAXE(100010); const int MAXK(6); const int HSIZE(31313); const int SIGMA_SIZE(26); const int MAXH(19); const int INFI((INT_MAX-1) >> 1); const ULL BASE(31); const LL LIM(10000000); const int INV(-10000); const int MOD(20100403); const double EPS(1e-7); const LF PI(acos(-1.0)); template<typename T> void checkmax(T &a, T b){if(b > a) a = b;} template<typename T> void checkmin(T &a, T b){if(b < a) a = b;} template<typename T> T ABS(const T &a){return a < 0? -a: a;} int sum[100010][6]; int table[100010][6]; struct ELE { int value, ind; ELE(){}; ELE(int v_, int i_): value(v_), ind(i_){} }; deque<ELE> que[6]; int main() { int N, M, K, L; while(~scanf("%d%d%d%d", &N, &M, &K, &L)) { for(int i = 1; i <= M; ++i) for(int j = 1; j <= N; ++j) scanf("%d", sum[j]+i); for(int i = 1; i <= N; ++i) for(int j = 1; j <= M; ++j) sum[i][j] += sum[i-1][j]; for(int i = 1; i <= M; ++i) { que[i].clear(); que[i].push_back(ELE(0, 0)); } for(int i = 1; i <= N; ++i) { for(int j = 1; j <= M; ++j) { while(!que[j].empty() && i-que[j].front().ind > L) que[j].pop_front(); table[i][j] = que[j].front().value+sum[i][j]; } for(int j = 1; j <= M; ++j) for(int k = 1; k <= M; ++k) if(j != k) { int tv = table[i][j]-sum[i][k]+K; while(!que[k].empty() && tv <= que[k].back().value) que[k].pop_back(); que[k].push_back(ELE(tv, i)); } } int ans = INFI; for(int i = 1; i <= M; ++i) checkmin(ans, table[N][i]); printf("%d\n", ans); } return 0; }