Training@USC Greedy Tino

思路:

     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     }

 

posted on 2012-11-17 23:58  yumao  阅读(245)  评论(0编辑  收藏  举报

导航