PKU 1293 Duty Free Shop

http://poj.org/problem?id=1293

2種類のチョコレートがそれぞれm個,l個ある。
そして、n個の箱があり、それぞれチョコレートをC_i個入れなければいけない。

異なる種類のチョコレートを同じ箱に入れることなく、全ての箱をチョコレートで満たすことが出来るかどうかを判定し、出来る場合はm個あるほうのチョコレートをどの箱に入れるかを答えろというような問題。

dp[i番目の箱までみて、i番目の箱をチョコmを入れるのに使ったか][i番目の箱][チョコmをj個使った]
みたいなDPをして、経路復元みたいなことをしました。

int m,l;
int box[2000];
bool dp[2][2000][1001];

void solve(){
  int n;
  cin>>n;
  int sum=0;
  rep(i,n){
    cin>>box[i];
    sum+=box[i];
  }

  if(sum<=l){
    cout<<0<<endl;
    return;
  }
  memset(dp,0,sizeof(dp));  

  if(box[0]<=m) dp[0][0][box[0]] = true;
  dp[1][0][0]=true;
  
  for(int i=1;i<n;++i)
    for(int j=0;j<=m;++j){
      dp[1][i][j] |= dp[0][i-1][j]|dp[1][i-1][j];
      if(j>=box[i])
        dp[0][i][j] |= dp[0][i-1][j-box[i]]|dp[1][i-1][j-box[i]];
      if(sum-j>l || !dp[0][i][j]) continue;
      vector<int> use;

      bool flag=0;
      int tm=j;
      int tu=i;

      while(tu>=0){
        if(!flag){
          use.pb(tu);
          tm -= box[tu];
        }
        if(tm==0) break;
        if(tu==0) break;
        --tu;
        if(dp[0][tu][tm]) flag=0;
        else flag=true;
      }
      
      cout<<SZ(use);
      reverse(ALL(use));
      FOR(it,use) cout<<' '<<*it+1;
      cout<<endl;
      return;
    }
  
  cout<<"Impossible to distribute"<<endl;

}

main(){
  while(cin>>m>>l,m|l)
    solve();
}