[关闭]
@rg070836rg 2015-12-13T17:01:07.000000Z 字数 1023 阅读 1487

算法概论作业6.16 6.19 6.21 6.14

算法概论作业


6.16

  1. 本题目的起始顶点( home)可以访问多次,而且不必访问所有的顶点。以 B(S j , )来表示在 garage sale 集为 S ,结束位置为 j 的子问题上的最大收益值。注意 j 的前导顶点既可能是某个 garage sale,也可能是 home,于是有Dp方程:

DP方程:
0.png-23.7kB

6.19

DP方程:
0.png-18.2kB

代码如下:

  1. bool h[K][v];
  2. int j;
  3. //initialize
  4. h[0][0]=true;
  5. for(j=1;j<=v;j++)
  6. h[0][j]=false;
  7. for(j=1;j<=K;j++)
  8. h[j][0]=false;
  9. k=0;
  10. for(j=1;j<=v;j++)
  11. {
  12. for(int i=1;i<=n;i++)
  13. {
  14. While(k<K)
  15. {
  16. if(j==x[i] && k<=K)
  17. { h[k][j]=true; }
  18. else if(j>x[i] && k<K)
  19. { h[k][j]=h[k][j] || h[k-1][j-x[i]]; }
  20. k++;
  21. }
  22. }
  23. }
  24. return h[k][v];

6.21

  1. 分析:求最小覆盖的大小,即在树中去除最大的独立集,即是最大独立集的补集。

代码如下:

  1. const int MAXN=100;
  2. vector<int> G[MAXN]; //无根树
  3. int l[MAXN]; //结点层次
  4. int p[MAXN]; //根树
  5. int dp[MAXN]; //dp数组
  6. int sumC[MAXN]; //孩子DP和
  7. int sumS[MAXN]; //孙子DP和
  8. int maxL; //最大层次
  9. int n;
  10. int rootDp(int u)
  11. {
  12. //构造u根树
  13. p[u]=-1;
  14. maxL=-1;
  15. dfs(u,p[u]); //遍历
  16. for(int i=maxL;i>=0;--i)
  17. {
  18. for(int j=0;j<n;++j)
  19. {
  20. if(l[j]==i)
  21. {
  22. dp[j]=max(sumS[j]+1,sumC[j]);
  23. if(i-1>=0)
  24. {
  25. sumC[p[j]]+=dp[j];
  26. }
  27. if(i-2>=0)
  28. {
  29. sumS[p[p[j]]]+=dp[j];
  30. }
  31. }
  32. }
  33. }
  34. return dp[u];
  35. }

6.14

  1. 每次沿着边沿剪下一块布,这样剩余的布料又可以形成最多三块矩阵面料。设P(w,h),是在宽为 w ,高为 h的布料上所能得到的收益,考虑每一次切割式样的两种情况,于是有DP方程如下

01.png-23.8kB
是将第个式样按照给定的形状直接切下来时的收益,
则是将第个式样按照旋转 90 度后的形状切下来时的收益。
最后返回 即可。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注