CF392B
Jisouhaoti
前処理
被験者に与えられる対価は、我々が知っているようには最適ではない、ディスクのx Y([] []のコード)から移動され
フロイドのような前処理として最短の緩和動作は2つの列[] []の間の最適値bを得ました
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
scanf("%lld",&a[i][j]),b[i][j]=a[i][j];
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++) if(i!=j)
for(int k=1;k<=3;k++) if(k!=i&&k!=j)
b[i][j]=min(b[i][j],b[i][k]+b[k][j]);
ハチソンは、遺体を発見しました
クール分析、各転送Nディスクは、二つの輸送方法があります。
- この方法の一つ
- 方法二
我々は、すべての時間は、ディスクの最大コストは[] []に直接であり、n-1の残りの部分を覚えて再帰検索することにより得られることを知っています
ディスクは、再帰的に単にB [] []のうち、予め最適なソリューションを使用する場合
int dfs(int l,int r,int n){
if(f[l][r][n]) return f[l][r][n]; //已经走过,直接返回
if(n==1) return b[l][r]; //递归边界,只剩一个盘
int x=6-l-r; //表示中介盘,因为三个盘编号之和为6
int an1=dfs(l,x,n-1)+dfs(x,r,n-1)+a[l][r]; //方法一
int an2=(dfs(l,r,n-1)<<1)+dfs(r,l,n-1)+a[l][x]+a[x][r]; //方法二
return f[l][r][n]=min(an1,an2); //取个最优值
}
DFS(L、R、N)ディスクの数は、n-L rを溶液から移動される表します
だから、答えは、dfs(1,3,n)
この問題はint型を爆発することに注意してください
ACコード:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,a[5][5],b[5][5],f[5][5][50];
int dfs(int l,int r,int n){
if(f[l][r][n]) return f[l][r][n];
if(n==1) return b[l][r];
int x=6-l-r;
int an1=dfs(l,x,n-1)+dfs(x,r,n-1)+a[l][r];
int an2=(dfs(l,r,n-1)<<1)+dfs(r,l,n-1)+a[l][x]+a[x][r];
return f[l][r][n]=min(an1,an2);
}
signed main(){
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
scanf("%lld",&a[i][j]),b[i][j]=a[i][j];
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++) if(i!=j)
for(int k=1;k<=3;k++) if(k!=i&&k!=j)
b[i][j]=min(b[i][j],b[i][k]+b[k][j]);
scanf("%lld",&n);
printf("%lld",dfs(1,3,n));
}