紫书 习题 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
- 紫书 习题 9-8 uva1632
- 习题9-8 Uva1632
- UVa1632 dp 滚动数组 紫书习题9-8
- uva1632 dp
- uva1632(区间dp)
- 紫书 习题 9-8 uva 10163
- 习题9-8 uva1631
- 区间dp+ 滚动数组uva1632
- 紫书 p59 习题3-8
- 习题9
- 习题9
- 习题8
- 习题8
- 习题8
- 习题8
- C++ primer 习题8-7 9 10
- UVa #1632 Alibaba (习题9-8)
- 编程珠玑第一章 习题2,习题9
- JavaScript学习笔记8-jQuery异步调用方式
- hdu 4745 区间回文最长长度
- Android之Xutils
- ubuntu忘记密码
- 第一篇博客
- 紫书 习题 9-8 uva1632
- 安卓:回退栈,类似新闻的布局界面
- C/C++中“#”和“##”的作用和用法
- Fragment 与 Activity交互
- 三种获取LayoutInflater对象的方式
- 白驹过隙之大一总结第二话
- 第九课 3D空间中移动图像:
- BZOJ 1123 [POI2008]BLO 点双连通分量
- 项目实战No8 刷新 日历处理