Gym - 101196:F Removal Game(区间DP)
Posted hua-dong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym - 101196:F Removal Game(区间DP)相关的知识,希望对你有一定的参考价值。
题意:一个环状数组,给定可以删去一个数,代价的相邻两个数的gcd,求最小代价。
思路:区间DP即可,dp[i][j]表示[i,j]区间只剩下i和j时的最小代价,那么dp[i][j]=min dp[i][k]+dp[k][j]+gcd(a[[i],a[j])。带上注意不能加倍做,以为常数会乘8,TLE。这也是这道题通过率低的原因。
#include<bits/stdc++.h> using namespace std; const int maxn=110; const int inf=1e9+7; int dp[maxn][maxn],a[maxn]; int main() { int N,i,j,k,ans; while(~scanf("%d",&N)&&N){ for(i=1;i<=N;i++) for(j=1;j<=N;j++) dp[i][j]=inf; for(i=1;i<=N;i++) scanf("%d",&a[i]); for(j=1;j<N;j++){ for(i=1;i<=N;i++){ if(j==1){ if(i+j==N) dp[i][N]=0; else dp[i][(i+j)%N]=0; } else for(k=i+1;k<i+j;k++){ int tj=(i+j)%N; if(!tj) tj=N; int tk=k%N; if(!tk) tk=N; dp[i][tj]=min(dp[i][tj],dp[i][tk]+dp[tk][tj]+__gcd(a[i],a[tj])); } } } ans=dp[1][N]+__gcd(a[1],a[N]); for(i=1;i<=N;i++) for(j=i+1;j<=N;j++) ans=min(ans,dp[i][j]+dp[j][i]+__gcd(a[i],a[j])); printf("%d ",ans); } return 0; }
以上是关于Gym - 101196:F Removal Game(区间DP)的主要内容,如果未能解决你的问题,请参考以下文章
Gym - 101196G :That's One Hanoi-ed Teacher (递推)
gym/103049/problem G - Great Expectations(期望+二分)
codeforces gym101243 A C D E F G H J