1. 程式人生 > >Re0:DP學習之路 01揹包如何列印路徑?

Re0:DP學習之路 01揹包如何列印路徑?

虛擬碼

用二維陣列記錄,如果出現可以轉移的dp那麼記錄bk[當前體積][裝的物品]=1

輸出的時候倒推,如果存在連通的邊那麼輸出並且總共的體積減去輸出的體積

程式碼(uva-624,目前wa不明所以,網上的答案也是那麼輸出的,或許要輸出最多的物品?目前也不會這種玩法)

#include <bits/stdc++.h>
using namespace std;
int v[1000],dp[1000000],bk[1000][1000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,m;
  while(cin>>m>>n)
  {
    memset(dp,0,sizeof(dp));
    memset(bk,0,sizeof(bk));
    stack<int> st;
    for(int i=1;i<=n;i++)
    cin>>v[i];
    for(int i=1;i<=n;i++)
    for(int j=m;j>=v[i];j--)
    if(dp[j]<dp[j-v[i]]+v[i])
    {
      bk[j][i]=1;
      dp[j]=dp[j-v[i]]+v[i];
    }
    for(int i=n,j=m;i>=1;i--)
    if(bk[j][i])
    st.push(v[i]),j-=v[i];
    while(st.size())
    {
      cout<<st.top()<<" ";
      st.pop();
    }
    cout<<"sum:"<<dp[m]<<"\n";
  }
}