zoukankan      html  css  js  c++  java
  • 区间dp-zoj3541-The Last Puzzle

    题目链接:

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3541

    题目大意:

    在数轴上,有n个按钮,位置递增为d1,d2,..dn,每个按钮对应一个时间为t1,t2,...tn.每次每个按钮按下后,t1秒后会自动弹起来。每走单位距离花费单位时间,问以怎样的顺序按,能够保证所有 的按钮都能够被按下去。

    解题思路:

    区间dp.

    这题hdu 4053提交过不了,spj可能有问题。

    对于某一区间A~B的按钮,一定是先按某个端点,如果不是,假设先按中间的K,然后肯定要按一个端点,再之后会按另外一个端点,中间肯定会经过K点,所以先按k不如后按k。

    dp[i][j][0]表示在区间i~j内先按左边端点能达到的最小的时间,dp[i][j][1]表示先按右端点能达到的最小时间。

    dp[i][j][0]=Min(dp[i+1][j][0]+dp[i+1]-dp[i],dp[i+1][j]+dp[j][-dp[i]);

    path[i][j][]表示对应状态表示的端点(左还是右)。

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #define eps 1e-6
    #define INF 0x3fffffff
    #define PI acos(-1.0)
    #define ll __int64
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    
    #define Maxn 220
    
    ll dp[Maxn][Maxn][2];
    int pa[Maxn][Maxn][2];
    //dp[i][j][0]表示区间i~j从左边端点开始按 dp[][][1]表示从右边端点开始
    //path[i][j][k]表示与之对应的状态。
    int ti[Maxn],di[Maxn];
    int n;
    
    int main()
    {
       while(scanf("%d",&n)!=EOF)
       {
          for(int i=1;i<=n;i++)
             scanf("%d",&ti[i]);
          for(int i=1;i<=n;i++)
             scanf("%d",&di[i]);
          memset(dp,0,sizeof(dp)); //时间为0
          for(int gap=2;gap<=n;gap++)
          {
             for(int i=1;i+gap-1<=n;i++)
             {
                int j=i+gap-1;
    
                if(dp[i+1][j][0]+di[i+1]-di[i]<dp[i+1][j][1]+di[j]-di[i])
                {
                   dp[i][j][0]=dp[i+1][j][0]+di[i+1]-di[i];
                   pa[i][j][0]=0;//表示从左边过来
                }
                else
                {
                   dp[i][j][0]=dp[i+1][j][1]+di[j]-di[i];
                   pa[i][j][0]=1;//表示从右边走
                }
                if(ti[i]<=dp[i][j][0]||dp[i][j][0]>=INF)
                   dp[i][j][0]=INF;
    
                if(dp[i][j-1][1]+di[j]-di[j-1]<=dp[i][j-1][0]+di[j]-di[i])
                {
                   dp[i][j][1]=dp[i][j-1][1]+di[j]-di[j-1];
                   pa[i][j][1]=1; //从右边
                }
                else
                {
                   dp[i][j][1]=dp[i][j-1][0]+di[j]-di[i];
                   pa[i][j][1]=0;//从左边
                }
                if(ti[j]<=dp[i][j][1]||dp[i][j][1]>=INF)
                   dp[i][j][1]=INF; //置为无效状态
             }
          }
          int l,r,va;
          if(dp[1][n][0]<INF) //有效状态
          {
             printf("%d",1);
             l=2,r=n;
             va=pa[1][n][0];
          }
          else if(dp[1][n][1]<INF)
          {
             printf("%d",n);
             l=1,r=n-1;
             va=pa[1][n][1];
          }
          else
          {
             printf("Mission Impossible
    ");
             continue;
          }
          while(l<=r)
          {
             if(va==0)
             {
                printf(" %d",l);
                va=pa[l][r][0];
                l++;
             }
             else
             {
                printf(" %d",r);
                va=pa[l][r][1];
                r--;
             }
          }
          putchar('
    ');
       }
       return 0;
    }
    
    




  • 相关阅读:
    编译nginx增加fair模块
    使用CentOS8来部署php7.4
    通过PHP代码将大量数据插入到Sqlite3
    不同程序语言处理加密算法的性能对比(PHP/Golang/NodeJS)
    CentOS8更换国内YUM源
    MySQL获取上月第一天、上月最后日、本月第一天、本月最后日的方法
    GO
    Go-数据类型以及变量,常量,函数,包的使用
    GO语言介绍以及开发环境配置
    利用python代码操作git
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3299258.html
Copyright © 2011-2022 走看看