算法入门经典第二版 紫书 第9章 动态规划初步

9-1  http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3466

书上是递推的,我写了个记忆化搜索dp

有3种决策,左边的车,右边的车,原地不动,

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define mt(a,b) memset(a,b,sizeof(a))
 5 using namespace std;
 6 const int inf=0x3f3f3f3f;
 7 const int M=64;
 8 int w[M];
 9 bool left[M][256];
10 bool right[M][256];
11 int dp[M][256];
12 bool vis[M][256];
13 int N,T;
14 int dfs(int n,int t){
15     if(vis[n][t]) return dp[n][t];
16     vis[n][t]=true;
17     int& ans=dp[n][t];
18     ans=inf;
19     if(n>1&&t>=w[n-1]){
20         for(int i=0;i<=t-w[n-1];i++){
21             if(left[n-1][i]){
22                 ans=min(ans,dfs(n-1,i)+t-i-w[n-1]);
23             }
24         }
25     }
26     if(n<N&&t>=w[n]){
27         for(int i=0;i<=t-w[n];i++){
28             if(right[n+1][i]){
29                 ans=min(ans,dfs(n+1,i)+t-i-w[n]);
30             }
31         }
32     }
33     for(int i=0;i<=t;i++){
34         ans=min(ans,dfs(n,i)+t-i);
35     }
36     return ans;
37 }
38 int main(){
39     int m,x,cas=1;
40     while(~scanf("%d",&N),N){
41         scanf("%d",&T);
42         for(int i=1;i<N;i++){
43             scanf("%d",&w[i]);
44         }
45         mt(left,0);
46         mt(right,0);
47         scanf("%d",&m);
48         while(m--){
49             scanf("%d",&x);
50             for(int i=1;i<=N;i++){
51                 if(x>T) break;
52                 left[i][x]=true;
53                 x+=w[i];
54             }
55         }
56         scanf("%d",&m);
57         while(m--){
58             scanf("%d",&x);
59             for(int i=N;i>=1;i--){
60                 if(x>T) break;
61                 right[i][x]=true;
62                 x+=w[i-1];
63             }
64         }
65         mt(vis,0);
66         vis[1][0]=true;
67         dp[1][0]=0;
68         int ans=dfs(N,T);
69         printf("Case Number %d: ",cas++);
70         if(ans==inf) puts("impossible");
71         else printf("%d
",ans);
72     }
73     return 0;
74 }
View Code

9-2 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=378

书上定义的是dp【i】【j】表示第i 个块在顶面,j 是高、 其中i有n种,j有3种,状态3n,这种定义的转移方程有空再推

我定义的是 dp【x】【y】表示以x为宽y为长的矩形为底面,所能得到的最大高度,然后我是不断的往底面加块,通过转移就可以看出来,那么状态是6n,因为n组xyz,每一种可以产生A(3,2),所以状态6n。记忆化搜索dp

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<map>
 5 #define mt(a,b) memset(a,b,sizeof(a))
 6 using namespace std;
 7 struct G{
 8     int x,y,z;
 9 }a[32];
10 int n;
11 typedef pair<int,int> pii;
12 map<pii,int> dp;
13 int dfs(int x,int y){
14     pii p=make_pair(x,y);
15     if(dp.count(p)) return dp[p];
16     int ans=0;
17     for(int i=0;i<n;i++){
18         int tx=a[i].x;
19         int ty=a[i].y;
20         int tz=a[i].z;
21         if(tx>x&&ty>y)
22             ans=max(ans,dfs(tx,ty)+tz);
23         if(ty>x&&tx>y)
24             ans=max(ans,dfs(ty,tx)+tz);
25         if(tx>x&&tz>y)
26             ans=max(ans,dfs(tx,tz)+ty);
27         if(tz>x&&tx>y)
28             ans=max(ans,dfs(tz,tx)+ty);
29         if(ty>x&&tz>y)
30             ans=max(ans,dfs(ty,tz)+tx);
31         if(tz>x&&ty>y)
32             ans=max(ans,dfs(tz,ty)+tx);
33     }
34     return dp[p]=ans;
35 }
36 int main(){
37     int cas=1;
38     while(~scanf("%d",&n),n){
39         int big=0;
40         for(int i=0;i<n;i++){
41             scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
42             big=max(big,a[i].x);
43             big=max(big,a[i].y);
44             big=max(big,a[i].z);
45         }
46         dp.clear();
47         int ans=dfs(0,0);
48         printf("Case %d: maximum height = %d
",cas++,ans);
49     }
50     return 0;
51 }
View Code

 9-3 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=446&page=show_problem&problem=4093

待补

end

原文地址:https://www.cnblogs.com/gaolzzxin/p/4495352.html