vijos 1243 ——DP
7258 단어 dp
f[i][j][k]=f[i−1][j][k−1]+t[i][j](k>1)
그리고:
f[i][j][k] = min{f[i - 1][p][t]} + cost + t[i][j](k == 1 && t <= L && p != j)
이렇게 하면 틀림없이 50%의 데이터를 통과할 수 있을 것이다. 그리고 나는 저녁에 생각해서 사실 k의 1차원은 아무 소용이 없다는 것을 발견했다. 왜냐하면 우리는 k=1의 상황만 알면 반드시 k>1의 상황을 알 수 있기 때문이다.
그리고 한 단어가 내 머릿속에 떠올랐다.
단조로운 대열.
f[i][j]를 설정하면 i개 공사에서 j개 기계로 하는 최소 비용을 나타낸다.
변환 방정식은 다음과 같습니다.
f[i][j]=min(f[v][p]+sum[v−>i][j]+cost)
접두어 및 최적화:
f[i][j]=min(f[v][p]+sum[i][j]−sum[v][j]+cost)
f[i][j]=min(f[v][p]−sum[v][j])+sum[i][j]+cost;
그리고 곰곰이 생각해 보면 i 앞에 있는 모든 v를 그대로 유지하면: i - v < L이면 된다.
또한 이러한 성격을 유지하는 동시에 O(1) 조회의 합법적인 최소치를 확보하면 된다.
누드의 단조로운 대열이 됐어..
우리는 최소치를 찾을 때 팀 헤드를 직접 가져와 팀 헤드가 합법적인지 확인하고 합법적이지 않으면 팀 헤드를 튀어나와 계속 판정한다.
이 DP 값을 받았을 때 f[i][j]로 다른 대기열을 업데이트하면 됩니다.
그리고 자신이 이 이론을 잘 알지만 문제를 약간 베껴서 풀었는데...
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define Rep(i,n) for(int i = 1;i <= n;i ++)
#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)
using namespace std;
void rd(int &x)
{
x = 0;bool flag = 0;
char ch = getchar();
while((ch > '9' || ch < '0') && ch != '-')ch = getchar();
if(ch == '-')flag = 1,ch = getchar();
while(ch >= '0' && ch <= '9')x = 10 * x + ch - '0',ch = getchar();
x = flag ? -x : x;
}
const int N = 100005;
const int inf = int(2e+9) + 1 << 25;
int sum[6][N],m,n,cost,l,f[N][6],q[6][N][2],h[6],t[6];
// f[i][j] = min { f[v][p] - sum[v][j] } + sum[i][j] + k;
int main(){
// freopen("t1.txt","r",stdin);
//rd(m),rd(n),rd(cost),rd(l);
scanf("%d%d%d%d",&m,&n,&cost,&l);
Rep(i,n)
Rep(j,m){scanf("%d",&sum[i][j]);/*rd(sum[i][j]);*/sum[i][j] += sum[i][j - 1];}
Rep(i,m)
Rep(j,n)
f[i][j] = inf;
Rep(i,n)q[i][t[i]][0] = 0;
Rep(i,m)
{
Rep(k,n)
{
int Maxn = inf;
//int v = k,j = k;
while(h[k]<=t[k] && i-q[k][ h[k] ][0]>l) h[k]++;
/*int tt=q[k][ h[k] ][0],p=q[k][ h[k] ][1]; f[i][k]=min(f[i][k],f[tt][p]+sum[k][i]-sum[k][tt]+cost); */
int pos = q[k][h[k]][0],s = q[k][h[k]][1];
//while(h[k] < t[k] && i - pos > l)h[k] ++;
f[i][k] = min(f[pos][s] - sum[k][pos] + sum[k][i] + cost,f[i][k]);
}
Rep(k,n)
Rep(j,n) // f[i][j] q[v]
if(k != j){
while(h[j] <= t[j] && f[i][k]-sum[j][i]<= f[ q[j][t[j]][0] ][q[j][t[j]][1]] - sum[j][q[j][t[j]][0]]) t[j]--;
q[j][++ t[j]][0] = i,q[j][t[j]][1] = k;
}
}
int MA = inf;
Rep(i,n)MA = min(MA,f[m][i]);
printf("%d
",MA - cost);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.