紫书 习题 9-8 uva1632

来源:互联网 发布:mysql 5.x数据库中文版 编辑:程序博客网 时间:2024/06/03 09:10


题意:

有n个宝藏,每个都在一个位置p[i],在规定的时间t[i]就会消失。阿里巴巴要在宝藏消失前收集齐所有宝藏,问:有方法吗?有的话最少多少秒?

思路:

开始想的是用状态转移方程来一个个判断,不好写。看了题解知道在一段区间[l,r]要使时间最短必须从端点出来,然后果断写了一个记忆化搜索,tle了。再看题解,所有的递归函数都可以优化成,递推表达式。写了一个递推过了。

线上的动态规划必定要开俩自变量l,r。因为要判断是从l还是r出,加一个自变量p(0:从 l 出 ;1:从 r 出)

可以知道dp[l][r][0]=min (dp[l+1][r][0]+a[l+1]-a[l] ,   dp[l+1][r][1]+a[r]-a[l]);

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

这样子递推的循序也出来了

i--,j++;

当dp[l][r][p]>=b[l/r][p]时,将dp[l][r][p]=inf,表示不符合题意;

个人感悟:

刷题就把自己当个逗逼吧!

//tle dfs#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>using namespace std;const int maxn=10000+10;const int inf=0x3f3f3f3f;int a[maxn];int b[maxn];int dp[maxn][maxn][2];int dfs(int l,int r,int p){    if(dp[l][r][p]!=-1) return dp[l][r][p];    if(r==l)    {        dp[l][r][p]=0;        return 0;    }    if(p==0)    {        //cout<<l<<" "<<r<<endl;        dp[l][r][p]=min(dfs(l+1,r,0)+a[l+1]-a[l] , dfs(l+1,r,1)+a[r]-a[l]);        if(dp[l][r][p]>b[l])        {            dp[l][r][p]=inf;        }    }    else if(p==1)    {       // cout<<l<<" "<<r<<endl;        dp[l][r][p]=min(dfs(l,r-1,0)+a[r]-a[l] , dfs(l,r-1,1)+a[r]-a[r-1]);        if(dp[l][r][p]>b[r])        {            dp[l][r][p]=inf;        }    }    return dp[l][r][p];}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        for(int i=1;i<=n;i++)        {            scanf("%d %d",&a[i],&b[i]);            //cout<<a[i]<<" "<<b[i]<<endl;        }        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                dp[i][j][0]=dp[i][j][1]=-1;            }        }        int ans=min(dfs(1,n,0),dfs(1,n,1));        if(ans==inf)        {            printf("No solution\n");        }        else        {            printf("%d\n",ans);        }    }    return 0;}

//ac 递推#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>using namespace std;const int maxn=10000+10;const int inf =0x3f3f3f3f;int a[maxn];int b[maxn];int dp[maxn][maxn][2];int main(){    int n;    while(scanf("%d",&n)!=EOF)    {       for(int i=1;i<=n;i++)       {           scanf("%d %d",&a[i],&b[i]);       }      // memset(dp,0,sizeof(dp));       for(int i=n;i>0;i--)       {           for(int j=i+1;j<=n;j++)           {               dp[i][j][0]=min( dp[i+1][j][0]+a[i+1]-a[i] , dp[i+1][j][1]+a[j]-a[i]);               if(dp[i][j][0]>=b[i])               {                   dp[i][j][0]=inf;               }               dp[i][j][1]=min( dp[i][j-1][1]+a[j]-a[j-1] ,dp[i][j-1][0]+a[j]-a[i]);               if(dp[i][j][1]>=b[j])               {                   dp[i][j][1]=inf;               }           }       }       int ans=min(dp[1][n][0],dp[1][n][1]);       if(ans==inf)       {           printf("No solution\n");       }       else       {           printf("%d\n",ans);       }    }    return 0;}


0 0
原创粉丝点击