面试题 背包问题的具体应用 打印出对应的序号
2012-12-05 21:07
337 查看
这是我看到的一个公司的面试题目,出题目的公司不知道是哪一个了。特意转载他的题目 解法是我给的 可能不是最好的
A公司供应各种档次的营养套餐,假设菜单上共有n项失误m1,m2,m3..mn,每种食物mi的营养价值为vi,价格为pi。套餐中每种失误之多出现一次,请完成以下两个小题:
(1)请为顾客设计算法。求解总价格不超过M的营养价值最大的套餐。
(2)具体列出来
食物编号 营养价值 价格
m1 100 25
m2 225 50
m3 150 40
m4 150 30
m5 80 10
列出总价格不超过100的营养价值最大的套餐对应的食物编号,以及对应的最大营养价值。
这是一个典型的动态规划的问题:
可以使用填表发:
申请一个 5*100的数组
相当于二维的数组,横坐标表示价格,纵坐标表示食品种类数目,a[i][j]表示当物品的种类为i的时候,总价值最大为j的时刻的营养价值
有以下的递推公式
若:j<w[i] v[i][j]=v[i-1][j];
否则: j>=w[i]. v[i][j]=max{v[i-1][j],v[i-1][j-w[i]]+vi[i]};
我们使用一个二维数组来表示搜索的规则:
以下为整个程序的代码:
下面是程序截图:
A公司供应各种档次的营养套餐,假设菜单上共有n项失误m1,m2,m3..mn,每种食物mi的营养价值为vi,价格为pi。套餐中每种失误之多出现一次,请完成以下两个小题:
(1)请为顾客设计算法。求解总价格不超过M的营养价值最大的套餐。
(2)具体列出来
食物编号 营养价值 价格
m1 100 25
m2 225 50
m3 150 40
m4 150 30
m5 80 10
列出总价格不超过100的营养价值最大的套餐对应的食物编号,以及对应的最大营养价值。
这是一个典型的动态规划的问题:
可以使用填表发:
申请一个 5*100的数组
相当于二维的数组,横坐标表示价格,纵坐标表示食品种类数目,a[i][j]表示当物品的种类为i的时候,总价值最大为j的时刻的营养价值
有以下的递推公式
若:j<w[i] v[i][j]=v[i-1][j];
否则: j>=w[i]. v[i][j]=max{v[i-1][j],v[i-1][j-w[i]]+vi[i]};
我们使用一个二维数组来表示搜索的规则:
以下为整个程序的代码:
#define N 5 #define W 12 int w[] = {-1, 2,5,4, 3,1};//物体的价值数组 2 5 3 (1 2 4) int vi[] = {-1, 10,22,12,15,8};//营养数组 10 22 15 int v[N+1][W+1]; //v[i][j]表示物体的中i个物体的营养等于钱j的时候包含的最大营养价值 int T[N+1][W+1];//搜索标志数组 enum{Init,kUp,kLeft,kUpLeft}; void init() { int i, j; for (i = 0; i <= N; i++) for (j = 0; j <= W; j++) { T[i][j]=0; v[i][j] = -1; } for (i = 0; i <= N; i++) { v[i][0]=0; T[i][0]=0; } for (i=0; i <= W; i++) { v[0][i] = 0; T[0][i]=0; } } int MKFnapsack_MEMOIZE(int N1,int W1) { for(int i=1;i<=N1;i++) { for(int j=1;j<=W1;j++) { if(j<w[i]) v[i][j]=v[i-1][j]; else { int value; int t1=v[i-1][j]; int t2=v[i-1][j-w[i]]+vi[i]; if(t1>=t2) { value=t1; } else { value=t2; T[i][j]=kUpLeft; } v[i][j]=value; } } } return v[N1][W1]; } void print_v(int N1,int W1) { for(int i=0;i<=N1;i++) { for(int j=0;j<=W1;j++) { cout<<v[i][j]<<" "; } cout<<endl; } } void print_T(int N1,int W1) { for(int i=0;i<=N1;i++) { for(int j=0;j<=W1;j++) { cout<<T[i][j]<<" "; } cout<<endl; } } void Find_T_V(int i,int j) { if(T[i][j]==0) Find_T_V(i-1,j); else { cout<<"编号:"<<i<<endl; int a=v[i][j]-vi[i]; if(a==0) return; int k=0; while(a!=v[i][k]) { k++; } Find_T_V(i,k); } } int main() { init(); printf("memoize most value is:%d\n", MKFnapsack_MEMOIZE(N, W)); print_v(N,W); cout<<"..."<<endl; print_T(N,W); Find_T_V(N,W); return 0; }
下面是程序截图:
相关文章推荐
- 0-1背包问题(需要输出具体背包序号)
- 剑指offer-4-面试题20:顺时针打印矩阵(画图使抽象问题形象化)
- 背包问题思想的一个应用
- 背包问题的应用
- 中兴面试题:简单的背包问题的两种思路
- 0-1背包和完全背包问题应用
- 背包问题应用
- 背包问题——“完全背包”详解及实现(包含背包具体物品的求解)
- 九章算法面试题58 背包问题
- dp中滚动数组的应用:01背包、POJ 1159 Palindrome、多段图路径问题
- 背包问题应用
- 由一道面试题“打印二叉树中和为某一值的路径”想到的二叉树的创建问题。
- 剑指offer_面试题12_打印1到最大的n位数(大数问题)
- 九章算法面试题59 背包问题II
- 背包问题应用(转) 讲的很详细
- 剑指offer:(20)画图让抽象问题更具体:顺时针打印矩阵
- web应用下的安全问题以及tomcat/nginx对应解决方法(持续更新、亲测可解决问题)
- 背包问题——“01背包”详解及实现(包含背包中具体物品的求解)
- 笔试和面试题(6)--背包问题
- 背包问题——“01背包”详解及实现(包含背包中具体物品的求解)