2019 뉴커머스 여름방학 멀티스쿨 캠프(10차전) J Wood Processing
27335 단어 DP
dp[i][j]
는 전j
개 합성i
개 널빤지의 최소 소비 면적을 나타낸다.전이 방정식은 dp [i] [j] = m in(dp [ii-1] [k] + s um [j]: [j] [j] [j] = m [k] = m in (dp [ii 1] [k] [j] [k] + h [k] (w [k]), d p [i] [j] dp[i] [j] = min(dp [i-1] [k] [k] + sum [j] [k] - s[k] [[k] + h[k] + h[k] + h[[[k+ 1] + (w[[[k] * (w[[j] - [k] [[k] [[k] [[k]] [j] [[j]] [j] [j]]]]]]]]]]]]k]+sum[j]--sum[k]+h[k+1]∗(w[j]--w[k]), dp[i][j]) 중 ww는 너비 접두사와 sum sum sum는 면적 접두사와전이의 공헌은,가령 kk에서 lll보다 낫다고 가정하면,다음과 같이: dp [ii-4-1] [k] + s u m [j]: [k] - h[k + 1] (w [j] [k] + s u m [k] +sum[j]-sum[l]+h[l+1]*(w[j]-w[l])dp[i-1][k]+sum[j]--sum[k]--h[k+1]∗(w[j]--w[k])=dp[i-1][l]+sum[j]--sum[l]+h[l+1]?(w[j]]-w[wl]]]]]-[wwwl]]][wwl]) 병합 항목화 간략화,(d p [i 내지 1] [k] 시우 m [k] + h [k + 1] 및 w [k]) - (dp [i 1] [l] [l] [k] - [k] - [k + h [k + 1] - h [k + 1] - h [k + 1] - h [l + 1] <w [j] [j] [w[j] [dp[i-1] [i-1] [k] [k] + [k] + h [k] w [k] w [k] w [k] w [k] w [k] + 1] - [k] [k] [w[k] [k] [h[k] [k] [k] [k] [k+ + 1] [k] [k] [k] [k] [k] [w] [k] [h[{h[k+1]-h[l+1]}h[k+1]--h[l+1](dp[i-1][k]--sum[k]+h[k+1]\w[k])--(dp[i-1][l]--sum[l]+h[l+1]\w[l])
#include "bits/stdc++.h"
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef __int128 LLL;
typedef pair<LLL, LLL> P;
#define VNAME(value) (#value)
#define bug printf("*********
");
#define debug(x) cout<
#define mid ((l + r) >> 1)
#define chl 2 * k + 1
#define chr 2 * k + 2
#define lson l, mid, chl
#define rson mid + 1, r, chr
#define eb(x) emplace_back(x)
#define pb(x) emplace_back(x)
#define mem(a, b) memset(a, b, sizeof(a));
const LL mod = (LL) 1e9 + 7;
const int maxn = (int) 5e3 + 5;
const LL INF = 0x7fffffff;
const LL inf = 0x3f3f3f3f;
const double eps = 1e-8;
#ifndef ONLINE_JUDGE
clock_t prostart = clock();
#endif
void f() {
#ifndef ONLINE_JUDGE
freopen("../data.in", "r", stdin);
#endif
}
template<typename T>
void read(T &w) {//
char c;
while (!isdigit(c = getchar()));
w = c & 15;
while (isdigit(c = getchar()))
w = w * 10 + (c & 15);
}
template<typename T>
void output(T x) {
if (x < 0)
putchar('-'), x = -x;
int ss[55], sp = 0;
do
ss[++sp] = x % 10;
while (x /= 10);
while (sp)
putchar(48 + ss[sp--]);
}
LLL dp[maxn][maxn];
P dat[maxn];
LLL sum[maxn];
LLL w[maxn];
LLL getup(int i, int j, int k) {
return (dp[i - 1][j] - sum[j] + w[j] * dat[j + 1].first) -
(dp[i - 1][k] - sum[k] + w[k] * dat[k + 1].first);
}
LLL getdown(int j, int k) {
return dat[j + 1].first - dat[k + 1].first;
}
LLL getdp(int i, int j, int k) {
return dp[i - 1][k] + sum[j] - sum[k] - dat[k + 1].first * (w[j] - w[k]);
}
int p[maxn];
int main() {
f();
int n, k;
read(n);
read(k);
for (int i = 1; i <= n; i++) {
read(dat[i].second);
read(dat[i].first);
}
sort(dat + 1, dat + n + 1);
for (int i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + dat[i].second * dat[i].first;
w[i] = w[i - 1] + dat[i].second;
}
mem(dp, inf);
dp[0][0] = 0;
for (int i = 1; i <= k; i++) {
int head = 0, tail = 1;
for (int j = 1; j <= n; j++) {
while (head + 1 < tail && getup(i, p[head + 1], p[head]) <= getdown(p[head + 1], p[head]) * w[j])head++;
dp[i][j] = getdp(i, j, p[head]);
while (head + 1 < tail && getup(i, p[tail - 1], p[tail - 2]) * getdown(j, p[tail - 1]) >
getup(i, j, p[tail - 1]) * getdown(p[tail - 1], p[tail - 2]))
tail--;
p[tail++] = j;
}
}
output(dp[k][n]);
puts("");
#ifndef ONLINE_JUDGE
cout << " :" << 1.0 * (clock() - prostart) / CLOCKS_PER_SEC << endl;
#endif
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[BOJ]11048(python)python 풀이 DP를 이용해 풀이 보통 이런 문제는 dfs나 bfs로 풀이하는 것이여서 고민을 했는데 이 문구 덕분에 DP 를 이용해 풀이할 수 있었다 뒤로 돌아가는 등의 경우를 고려하지 않아도 되기 때문이다 코...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.