算法入门经典第二版 紫书 第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\n",ans); 72 } 73 return 0; 74 }
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\n",cas++,ans); 49 } 50 return 0; 51 }
待补
end