zoukankan      html  css  js  c++  java
  • spoj14846 Bribe the Prisoners

    看来我还是太菜了,这么一道破题做了那么长时间......

    传送门

    分析

    我首先想到的是用状压dp来转移每一个人是否放走的状态,但是发现复杂度远远不够。于是我们考虑区间dp,dpij表示i到j区间的所有罪犯全部放走的最小花费,于是我们可以将一个区间(i,j)分为(i,k-1),(k+1,j)和k这个点,表示先取走点k的人,这样这个区间就被分成了两个,于是我们便可以转移的。详见代码。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    int pl[1100],dp[1100][1100];
    inline void init(){
          memset(dp,0x7f,sizeof(dp));
    }
    int main(){
          int n,m,i,j,k,t; 
          scanf("%d",&t);
          for(int _=1;_<=t;_++){
              init();
              scanf("%d%d",&m,&n);
              for(i=1;i<=n;i++)
                scanf("%d",&pl[i]);
              pl[n+1]=m+1;
              for(i=1;i<=n;i++)
                dp[i][i]=pl[i+1]-pl[i-1]-2;
              for(i=2;i<=n;i++)
                for(j=1;j+i-1<=n;j++){
                    dp[j][j+i-1]=min(dp[j+1][j+i-1],dp[j][j+i-2]);
                  for(k=j+1;k<j+i-1;k++)
                    dp[j][j+i-1]=min(dp[j][j+i-1],dp[j][k-1]+dp[k+1][j+i-1]);
                  dp[j][j+i-1]+=pl[j+i]-pl[j-1]-2;
                }
              printf("Case #%d: ",_);
              printf("%d
    ",dp[1][n]);
          }
          return 0;
    }
  • 相关阅读:
    PlantUML —— 应用于 Eclipse 的简单快速的 UML 编辑软件
    PlantUML类图
    Java 基于log4j的日志工具类
    RabbitMQ Hello world(二)
    redis lua 初体验
    mysql 批处理 innodb_flush_at_trx_commit 测试分析
    mysql 服务日志 5.7.29
    redis 浅谈事务
    redis list 基本操作
    redis hash 基本操作
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9462279.html
Copyright © 2011-2022 走看看