题目链接 :uva CD
不知道错在哪,改了好久,感觉思路没问题但就是wa了,希望以后能看出来,错误代码教程:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int v[10005];
int dp[10005][10005];
void out(int x,int y)
{
int array[1005];
int k=0;
memset(array,0,sizeof(array));
while(x!=0&&y!=0)
{
if(dp[x][y]==dp[x-1][y])x--;
else
{
array[k++]=v[x];
y-=v[x],x--;
}
}
if(array[k]!=0)cout<<array[k]<<" ";
for(int i=k-1;i>=0;--i)
{
cout<<array[i]<<" ";
}
}
int main()
{
int n,m;
while(cin>>m>>n)
{
memset(v,0,sizeof(v));
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;++i)
scanf("%d",&v[i]);
for(int i=1;i<=n;++i)
{
for(int j=v[i];j<=m;++j)
{
dp[i][j]=dp[i-1][j];
dp[i][j]=max(dp[i][j],dp[i-1][j-v[i]]+v[i]);
}
}
out(n,m);
cout<<"sum:"<<dp[n][m]<<endl;
}
}
改出来了,还是思考的不够仔细,错误原因:
当j从v[i]开始有个弊端,就是你无法对j<v[i]时的dp[i][j]进行更新导致dp[i][j]==0,如果这种情况出现在最后(v[n]大于m)你就凉了
-----dp[n][j]始终为零,空间优化下不需要对dp[j]进行复制只需对其维护即可,记住这点不同;
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int v[10005];
int dp[10005][10005];
void out(int x,int y)
{
int array[1005];
int k=0;
memset(array,0,sizeof(array));
while(x!=0&&y!=0)
{
if(dp[x][y]==dp[x-1][y])x--;
else
{
array[k++]=v[x];
y-=v[x],x--;
}
}
for(int i=k-1;i>=0;--i)
{
cout<<array[i]<<" ";
}
}
int main()
{
int n,m;
while(cin>>m>>n)
{
memset(v,0,sizeof(v));
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;++i)
scanf("%d",&v[i]);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
{
if(j>=v[i])dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+v[i]);
else dp[i][j]=dp[i-1][j];
}
}
out(n,m);
cout<<"sum:"<<dp[n][m]<<endl;
}
}
题中记路的深搜写法:
int flag;
int divs[10005];
void bfs(int k,int sum)
{
if(sum==dp[n][m])
{
flag=1;
return ;
}
if(k==n+1||flag)return;
/*if(sum+v[k]>dp[n][m])return ;
这行代码加的有点累赘,而且要知道这行代码会将整个搜索支斩去,导致结果。。。。。
*/
if(sum+v[k]<=dp[n][m])
{
divs[k]=1;
bfs(k+1,sum+v[k]);
if(flag==1)return ;
divs[k]=0;
}
if(!flag)bfs(k+1,sum);
}