您的位置:首页 > 其它

** 浙大PAT甲级 1068 01背包问题

2016-08-27 10:34 751 查看
这个题是dp01背包问题,dp[i][j]表示在j容量下前i个货币最大利益,但是难点在如何输出最小序列。

将输入的数按递减顺序排序,mark[i][j]==1表示在容量为j时的最大的利益情况下,加入了第i个货币。

然后进行回溯输出。

AC代码:

#include<iostream>
#include<map>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<list>
#include<set>
#include<stack>
#include<cmath>
#include<vector>
#define inf -100000000
using namespace std;
int a[10004];
int dp[10004][105];
int mark[10004][105];
bool cmp(int x,int y)
{
return x>y;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
for(int j=m;j>=a[i];j--)
{
int tmp=dp[i-1][j-a[i]]+a[i];
if(dp[i-1][j]>tmp)
{
dp[i][j]=dp[i-1][j];
}
else
{
dp[i][j]=tmp;
mark[i][j]=1;
}
}
}
if(dp
[m]!=m)
{
printf("No Solution");
}
else
{
vector<int> v;
while(m)
{
while(!mark
[m])
{
n--;
}
v.push_back(a
);
m-=a
;
n--;
}
int i;
for(i=0;i<v.size()-1;i++)
{
printf("%d ",v[i]);
}
printf("%d",v[i]);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: