[Solution] bzoj1190: [HNOI2007] Neverland Orbs (Dynamic Programming)

bzoj1190 , too lazy to copy, poke me poke me

Solution:

  • This question is actually a knapsack (grouped knapsack), but because the number is relatively large, it is necessary to reconstruct the dp formula. It took three days to understand.
  • \(dp[i][j]\) represents the maximum value when the backpack volume is \(j*2^i\) .
  • First of all, because each item must be \(a*2^b\) , we can do it according to the \(b\) value first according to the ordinary grouped backpack, and process the \(b\) value corresponding to the \ (dp\) value
  • Then we just want to accumulate these \(dp\) values. It is obviously not appropriate to choose the largest value of each group, because there may be space left in each group, and the accumulated space of the remaining space can also put items. Let's use \( dp\) method:
    \[dp[i][j] = max(dp[i][j] , dp[i][jk]+dp[i-1][2*k+(w>>(i- 1))])\]
  • \(i\) represents the power, \(j\) represents the coefficient, \(k\) represents how many positions are given to the \(i-1\) power
  • Our power is enumerated from small ( \(1\) ) to large ( \(W\) highest bit), and the coefficient is enumerated from large to small, to ensure that the maximum value on the \(i\) bit has not been updated , that is, excluding the items in the previous position ( \(2^{i-1}\) ), and then add the \(dp\) value of the maximum space on the previous layer ( \(i-1\) ) ( Because the space is the largest, the stored value must be the largest)
  • In addition, there is a small detail. We need to process each group of backpacks to \(2\) times in the previous preprocessing, because when updating later, the space of the \(i\) layer will be passed to \(i-1\ ) layer, for example, the \(i\) layer frees up \(k\) space, that is, the \(i-1\) layer has more space for \(2*k\) , plus the inside of \(W\) The space of \(i -1\) bits is the largest space of \(i-1\)
  • The final output \(dp[cnt][1]\) , \(cnt\) is the highest bit, because it is the highest bit, so the highest bit must be \(1\)
  • It's still quite confusing to see, click here , this blog is very detailed
  • It seems that the titles of \(HNOI2007\) are all cancerous 23333...

Code:

//It is coded by Ning_Mew on 4.19
#include<bits/stdc++.h>
#define LL long long
using namespace std;

const int maxn=107;

int n,cnt=0;
LL W,dp[maxn][2005],v,w;

int main(){
  while(1){
    memset(dp,0,sizeof(dp));
    scanf("%d%lld",&n,&W);
    if(n==-1)break;
    for(int i=1;i<=n;i++){
      scanf("%lld%lld",&w,&v);
      cnt=0;
      while(w%2==0)cnt++,w=w/2;
      //cout<<"w:"<<cnt<<' '<<w<<endl;
      for(int i=2000;i>=w;i--){
    dp[cnt][i]=max(dp[cnt][i],dp[cnt][i-w]+v);
      }
    }
    cnt=0;
    for(int i=30;i>=0;i--)if((W>>i)&1){cnt=i;break;}
    //cout<<"w:"<<cnt<<' '<<W<<endl;
    for(int i=1;i<=cnt;i++){
      for(int j=1000;j>=0;j--){
    for(int k=0;k<=j;k++){
      dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[i-1][2*k+((W>>(i-1))&1)]);
    }
      }
    }
    printf("%lld\n",dp[cnt][1]);
  }
  return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325059298&siteId=291194637