标签:
想出如何记录状态后就不难了,转移很好想,但也许略复杂。。。
dp(i,j,k)表示在处理第i个业务,另外2个在j,k处,转移的话就是可以移动a[i-1]、j或k,第一维可以滚动
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<ctime> 5 #include<cmath> 6 #include<iostream> 7 #include<algorithm> 8 #include<queue> 9 #include<stack> 10 #include<set> 11 #define clr(a,x) memset(a,x,sizeof(a)) 12 #define rep(i,l,r) for(int i=(l);i<(r);i++) 13 using namespace std; 14 typedef long long ll; 15 typedef pair<int,int> pii; 16 #define mkp(a,b) make_pair(a,b) 17 int read(){ 18 int ans=0,f=1; 19 char c=getchar(); 20 while(!isdigit(c)){ 21 if(c==‘-‘) f=-1; 22 c=getchar(); 23 } 24 while(isdigit(c)){ 25 ans=ans*10+c-‘0‘; 26 c=getchar(); 27 } 28 return ans*f; 29 } 30 const int maxm=209,maxn=1009,inf=0x3fffffff; 31 int n,m,cur=1,pre=0,a[maxn],d[maxm][maxm],dp[2][maxn][maxn]; 32 int main(){ 33 freopen("test.in","r",stdin); 34 m=read(); 35 rep(i,1,m+1) 36 rep(j,1,m+1) d[i][j]=read(); 37 for(n=1;~scanf("%d",a+n);n++);n--; 38 rep(j,1,m+1) 39 rep(k,1,m+1) dp[cur][j][k]=inf; 40 dp[cur][2][3]=d[1][a[1]]; 41 dp[cur][1][3]=d[2][a[1]]; 42 dp[cur][1][2]=d[3][a[1]]; 43 rep(i,1,n+1){ 44 cur^=1;pre^=1; 45 rep(j,1,m+1) 46 rep(k,1,m+1) dp[cur][j][k]=inf; 47 rep(j,1,m+1) 48 rep(k,j+1,m+1){ 49 dp[cur][j][k]=min(dp[cur][j][k],dp[pre][j][k]+d[a[i-1]][a[i]]); 50 dp[cur][min(k,a[i-1])][max(k,a[i-1])]=min(dp[cur][min(k,a[i-1])][max(k,a[i-1])],dp[pre][j][k]+d[j][a[i]]); 51 dp[cur][min(j,a[i-1])][max(j,a[i-1])]=min(dp[cur][min(j,a[i-1])][max(j,a[i-1])],dp[pre][j][k]+d[k][a[i]]); 52 } 53 } 54 int ans=inf; 55 rep(i,1,m+1) 56 rep(j,i+1,m+1) ans=min(ans,dp[cur][i][j]); 57 printf("%d\n",ans); 58 return 0; 59 }
标签:
原文地址:http://www.cnblogs.com/chensiang/p/4998983.html