zoukankan      html  css  js  c++  java
  • 石子合并问题(圆形版)

    首先来个题目链接:http://acm.uestc.edu.cn/#/problem/show/886

    题目:

    方老师金币堆

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
     

    虽然方老师赚到了很多钱,但是有些钱却非常难处理,经常会有人会以一大袋金币的方式来支付方老师的演讲报酬。现在方老师家里已经放置了N袋金币了,每一袋金币质量为Ai,他想把这些金币合并在一袋里面,然后存到银行去,于是方老师把这N袋金币围成一个圈,每一次他可以把相邻两袋金币合并,并消耗两袋金币质量总和的体力,他想让你帮他算下,他最少消耗多少体力可以完成这项工作。

    注意:开始时第i袋金币与第i+1袋金币相邻,第1袋金币与第N袋金币相邻。

    Input

    输入有多组数据

    每组数据第一行有1个正整数N,表示有N袋金币(1N100)

    每组数据第二行N个整数,第i个整数表示第i袋金币的质量为Ai(1Ai50)

    Output

    输出1个整数,表示方老师最少消耗的体力。

    Sample input and output

    Sample InputSample Output
    4
    1 1 1 1
    8

    思路:dp[i][r]=min(dp[i][r],dp[i][k-1]+dp[(i+k-1)%n+1][r-k])。其中,dp[i][r]表示第i堆到第i+r堆的最优解。

    最朴素的算法:

     1 #include <fstream>
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cmath>
     7 using namespace std;
     8 
     9 const int N=205;
    10 const int INF=0x7fffffff;
    11 int n;
    12 int a[N],sum[N],dp[N][N];
    13 
    14 int f();
    15 
    16 int main(){
    17     //freopen("D:\input.in","r",stdin);
    18     while(~scanf("%d",&n)){
    19         sum[0]=0;
    20         for(int i=1;i<=n;i++){
    21             scanf("%d",&a[i]);
    22             sum[i]=sum[i-1]+a[i];
    23         }
    24         printf("%d
    ",f());
    25     }
    26     return 0;
    27 }
    28 int f(){
    29     for(int i=1;i<=n;i++)   dp[i][0]=0;
    30     for(int r=1;r<n;r++){
    31         for(int i=1;i<=n;i++){
    32             int j=i+r;
    33             dp[i][r]=INF;
    34             for(int k=1;k<=r;k++){
    35                 if(i+k>n)   dp[i][r]=min(dp[i][r],dp[i][k-1]+dp[(i+k)%n][r-k]);
    36                 else    dp[i][r]=min(dp[i][r],dp[i][k-1]+dp[i+k][r-k]);
    37             }
    38             if(i+r>n) dp[i][r]+=sum[(i+r)%n]+sum[n]-sum[i-1];
    39             else    dp[i][r]+=sum[i+r]-sum[i-1];
    40         }
    41     }
    42     int ans=INF;
    43     for(int i=1;i<=n;i++) ans=min(ans,dp[i][n-1]);
    44     return ans;
    45 }
    5ms

    四边形不等式优化:

     1 #include <fstream>
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cmath>
     7 using namespace std;
     8 
     9 const int N=205;
    10 const int INF=0x7fffffff;
    11 int n;
    12 int a[N],sum[N],dp[N][N],s[N][N];
    13 
    14 int f();
    15 
    16 int main(){
    17     //freopen("D:\input.in","r",stdin);
    18     while(~scanf("%d",&n)){
    19         sum[0]=0;
    20         for(int i=1;i<=n;i++){
    21             scanf("%d",&a[i]);
    22             sum[i]=sum[i-1]+a[i];
    23         }
    24         printf("%d
    ",f());
    25     }
    26     return 0;
    27 }
    28 int f(){
    29     for(int i=1;i<=n;i++)   dp[i][0]=0,s[i][0]=1;
    30     for(int r=1;r<n;r++){
    31         for(int i=1;i<=n;i++){
    32             int j=i+r;
    33             dp[i][r]=INF;
    34             for(int k=s[i][r-1];k<=s[i+1][r-1]+1;k++){
    35                 int t=dp[i][k-1]+dp[(i+k-1)%n+1][r-k];
    36                 if(dp[i][r]>t){
    37                     dp[i][r]=t;
    38                     s[i][r]=k;
    39                 }
    40             }
    41             if(i+r>n) dp[i][r]+=sum[(i+r)%n]+sum[n]-sum[i-1];
    42             else    dp[i][r]+=sum[i+r]-sum[i-1];
    43         }
    44     }
    45     int ans=INF;
    46     for(int i=1;i<=n;i++) ans=min(ans,dp[i][n-1]);
    47     return ans;
    48 }
    0ms

    关于四边形不等式优化,详见:http://www.cnblogs.com/jiu0821/p/4493497.html

  • 相关阅读:
    Ubuntu 20.04 不能远程连接
    CentOS 6.8 设置开机自动联网
    JSON 语法
    用友U8 | 【成本管理】用友U8卷积运算时警告提示:‘’有未记账非委外加工入库单代管挂账确认单‘’
    用友U8 | 【总账】总账结账时,对账不平
    用友U8 | 【应收款管理】取消核销操作
    用友U8 | 【总账】账簿明细账打印,选择科目打印,页数范围超过了430页,之后的内容都显示不出来
    用友U8 | 【存货核算】存货模块删除凭证时提示:当前凭证已经有实时核销处理,不能被作废(或删除)!
    用友U8 | 【存货核算】存货核算模块,凭证处理,查询凭证时,会计年度选择不到2021年度
    用友U8 | 【总账】科目辅助总账与科目辅助明细账数据不一样
  • 原文地址:https://www.cnblogs.com/jiu0821/p/4494219.html
Copyright © 2011-2022 走看看