Training@USC Greedy Tino

来源:互联网 发布:最新编程语言 编辑:程序博客网 时间:2024/05/02 04:38

思路:

     DP题;

     题意为给出n个橘子的重量,求其中最大的相等的和;

     用dp[i][j]表示第i个橘子放入时,扁担两端的差为 j 时的最大重量(此重量为扁担重的那头的);

     而橘子放入时,有四种可能:

    1.  放入时,放入较轻的一端;

           ① 扁担两端的差大于橘子的重量,那么放入后,重的那端的重量还是不变;

               dp[i][j-a[i]]=max{dp[i][j-a[i]],dp[i-1][j]};

           ② 扁担两端的差小于橘子的重量,那么放入后,轻的一端会变为重的一端;

               dp[i][a[i]-j]=max{dp[i][j-a[i],dp[i-1][j]+a[i]-j};

    2. 放入时,放入较重的一端;

               dp[i][j+a[i]]=max{dp[i][j+a[i]],dp[i-1][j]+a[i]};

    3. 不放入

               dp[i][j]=max{dp[i][j],dp[i-1][j]};

 

    要注意的是,有可能有橘子的重量为0的情况。这样的话,就可能扁担的一边可以放为0的橘子,一边可以不放东西也成立。

 

    代码:

 

View Code
 1 #include<iostream> 2 #include<string.h> 3 using namespace std; 4 int dp[105][2010]; 5 int a[105]; 6 int main(){ 7     int m; 8     cin>>m; 9     int times=0;10     while(m--){11             times++;12             int n;13             cin>>n;14             for(int i=0; i<n; i++){15                      cin>>a[i];16             }17             memset(dp, -1, sizeof(dp));18        //     memset(dp,0,sizeof(dp));19             for(int k=0; k<n; k++)20                  dp[k][a[k]]=0;21             for(int i=1; i<n; i++){22                     for(int j=0; j<=2005; j++){23                             if(dp[i-1][j] >= 0){24                                     if( dp[i][a[i]+j] < dp[i-1][j]){25                                         dp[i][a[i]+j] = dp[i-1][j];26                                         }27                                 if(a[i] >= j){28                                      if(dp[i][a[i]-j] < dp[i-1][j] + j)29                                       dp[i][a[i]-j] = dp[i-1][j]+j;              30                                  }31                                 else if(a[i] < j){32                                        if(dp[i][j-a[i]] < dp[i-1][j] + a[i])33                                             dp[i][j-a[i]] = dp[i-1][j]+a[i];34                                  }35                              }                                               36                         } 37                   /*      for(int g=0;g<2005;g++){38                                 dp[i][g]=dp[i-1][g]+a[i];39                                 }   */                   40                         for(int j=0; j<=2005; j++){41                            if(dp[i][j] < dp[i-1][j]){ 42                                 dp[i][j] = dp[i-1][j];43                          }44                          }45                 }     46               cout<<"Case "<<times<<": ";47       //        cout<<endl;48               cout<<dp[n-1][0]<<endl;                                49             }50   //    cin>>m;51     return 0;52     }

 

原创粉丝点击