[noip 2016] 교실 바 꾸 기 문제 풀이
고려 하 다두 교실 사이 의 최 단 로 는 플 로 이 드 로 미리 처리 할 수 있 고 나중에 O (1) 로 사용 하면 된다.상태 f [i] [j] [0... 1] 은 앞 i 칸 교실, j 칸, i 칸 바 뀌 지 않 겠 다 는 기 대 를 나타 낸다.
모든 상 태 는 이렇게 업데이트 할 수 있 습 니 다. dp [i] [j] [0] = min (dp [i] [0], dp [i - 1] [j] [0] + (double) dis [c [i]] [c [i - 1]]);dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][1]+dis[c[i]][c[i-1]]*(1-f[i-1])+dis[c[i]][d[i-1]]*f[i-1]); dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][0]+dis[c[i]][c[i-1]]*(1-f[i])+dis[d[i]][c[i-1]]*f[i]); double tmp=dis[c[i]][c[i-1]](1-f[i])(1-f[i-1])+dis[c[i]][d[i-1]]f[i-1](1-f[i]); tmp+=dis[d[i]][c[i-1]]f[i](1-f[i-1])+dis[d[i]][d[i-1]]*f[i]*f[i-1]; dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][1]+tmp); 길 어 보이 지만 실제로는 간단 합 니 다. 거의 네 가지 상황 을 토론 할 뻔 했 습 니 다. 손 이 떨 리 지 않도록 주의 하 시 면 됩 니 다.
#include
#define MIN(x,y,z) min(min(x,y),z)
using namespace std;
int n,m,v,e;
int dis[501][501];
int c[3001],d[3001];
double f[3001];
double dp[3001][3001][2];// i, j, i
double ans;
int x,y,z;
int read()
{
int x=0;
char c=getchar();
while(c>'9'||c<'0')c=getchar();
while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
return x;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&v,&e);
for(int i=1;i<=n;i++)scanf("%d",&c[i]);
for(int i=1;i<=n;i++)scanf("%d",&d[i]);
for(int i=1;i<=n;i++)scanf("%lf",&f[i]);
memset(dis,63,sizeof(dis));
for(int i=1;i<=v;i++)dis[i][i]=0;
for(int i=1;i<=e;i++)
{
scanf("%d%d%d",&x,&y,&z);
dis[x][y]=min(dis[x][y],z);
dis[y][x]=min(dis[y][x],z);
}
for(int k=1;k<=v;k++)
for(int i=1;i<=v;i++)
for(int j=1;j<=v;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
dp[i][j][0]=dp[i][j][1]=1e10;
dp[1][0][0]=dp[1][1][1]=0;
for(int i=2;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][0]+(double)dis[c[i]][c[i-1]]);
dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][1]+dis[c[i]][c[i-1]]*(1-f[i-1])+dis[c[i]][d[i-1]]*f[i-1]);
if(!j)continue;
dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][0]+dis[c[i]][c[i-1]]*(1-f[i])+dis[d[i]][c[i-1]]*f[i]);
double tmp=dis[c[i]][c[i-1]]*(1-f[i])*(1-f[i-1])+dis[c[i]][d[i-1]]*f[i-1]*(1-f[i]);
tmp+=dis[d[i]][c[i-1]]*f[i]*(1-f[i-1])+dis[d[i]][d[i-1]]*f[i]*f[i-1];
dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][1]+tmp);
}
}
ans=1e10;
for(int i=0;i<=m;i++)
ans=MIN(ans,dp[n][i][0],dp[n][i][1]);
printf("%.2f",ans);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C++의 디 버 깅 기술 과 우회 기법 을 자세히 설명 합 니 다.프로 세 스 가 실 행 될 때 위치 FS:[30h]는 PEB 의 기본 주 소 를 가리 키 며 디 버 깅 기술 을 실현 하기 위해 악성 코드 는 이 위 치 를 통 해 BeingDebugged 플래그 가 1 인지 확인 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.