zoukankan      html  css  js  c++  java
  • Gym

    题意:一个环状数组,给定可以删去一个数,代价的相邻两个数的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,这也是这道题通过率低的原因。dp[][]可以循环的,所以需要按照长度来转移状态。

    #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;
    }
  • 相关阅读:
    转:单链表有环判断及其起始位置定位
    转:C++经典排序算法总结
    转:堆排序
    转载:C++快速排序
    转载:平衡二叉树(AVL Tree)
    设计模式原则
    适配器模式
    单例模式
    工厂模式
    Head First设计模式 装饰者模式
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9419904.html
Copyright © 2011-2022 走看看