HDU1864+dp+类似背包

和以前的背包方程有点不同。

注意:一张支票上可能有多个可能相同的项目

这是AC的代码。

View Code
 1 /*
 2 首先dp[i][j]:表示从前i个中选择j个,则转移方程为:
 3 dp[i][j] = max( dp[ i-1 ][ j ](不选),dp[ i-1 ][ j-1 ]+val[i](选) );
 4 
 5 一开始用dp[ i ][ j ]:表示从前i个中选某些个得到不超过j的最大值,发现过不了。。。只好看别人代码。。。
 6 */
 7 
 8 #include<stdio.h>
 9 #include<string.h>
10 #include<stdlib.h>
11 #include<algorithm>
12 using namespace std;
13 const int maxn = 55;
14 double val[ maxn ];
15 double dp[ maxn ][ maxn ];
16 const double eps = 1e-7;//必须加精度。。。
17 int main(){
18     int n;
19     double V;
20     while( scanf("%lf%d",&V,&n)==2,n ){
21         int tn;
22         char str;
23         double p;
24         for( int i=0;i<n;i++ ){
25             double sum = 0;
26             int flag = 1;
27             scanf("%d",&tn);
28             double sum1,sum2,sum3;
29             sum1 = sum2 = sum3 =0;
30             while( tn-- ){
31                 scanf(" %c:%lf",&str,&p);
32                 if( str<'A'||str>'C' ) flag = -1;
33                 if( str=='A' ) sum1 += p;
34                 if( str=='B' ) sum2 += p;
35                 if( str=='C' ) sum3 += p;
36                 if( (sum1-600.0)>eps||(sum2-600.0)>eps||(sum3-600.0)>eps ) flag = -1;
37                 sum += p;
38             }
39             if( sum-1000.0>eps ) flag = -1;
40             if( flag==-1 ) val[ i ] = 0;
41             else val[ i ] = sum;
42         }
43         memset( dp,0,sizeof( dp ) );
44         double res = 0;
45         /*
46         for( int i=0;i<n;i++ ){
47             printf("val[%d]=%lf\n",i,val[i]);
48             for( int j=n;j>=i;j-- ){
49                 dp[ j ] = max( dp[ j ],dp[ j-1 ]+val[i] );
50                 if( dp[j]>res&&dp[j]<V) res = dp[j];
51             }
52         }
53         */
54         for( int i=1;i<=n;i++ ){
55         //printf("val[%d]=%lf\n",i-1,val[i-1]);
56             for( int j=1;j<=i;j++ ){
57                 dp[ i ][ j ] = max( dp[ i-1 ][ j ],dp[ i-1 ][ j-1 ]+val[ i-1 ] );
58                 if( (dp[i][j]-V<eps)&&(dp[i][j]-res>eps) ) res = dp[i][j];
59                 //printf("dp[%d][%d]=%lf\n",i,j,dp[i][j]);
60             }
61         }
62         printf("%.2lf\n",res);
63     }
64     return 0;
65 }
66         
67         

这是用100*money的AC代码。

View Code
 1 /*
 2 dp类似背包
 3 */
 4 #include<stdio.h>
 5 #include<string.h>
 6 #include<stdlib.h>
 7 #include<algorithm>
 8 #include<iostream>
 9 #include<queue>
10 #include<map>
11 #include<math.h>
12 using namespace std;
13 typedef long long ll;
14 //typedef __int64 int64;
15 const int inf = 0x7fffffff;
16 const double pi=acos(-1.0);
17 const double eps = 1e-6;
18 
19 struct node{
20     int vis;
21     int m;
22     int sum;
23 }a[ 36 ];
24 int dp[ 5000006 ];
25 
26 int main(){
27     int V,n;
28     double tt;
29     char name;
30     while( scanf("%lf%d",&tt,&n)==2 ){
31         if( n==0 ) break;
32         V = tt*100;
33         for( int i=0;i<n;i++ ){
34              scanf("%d",&a[i].m);
35              a[i].vis = true;
36              int sum = 0;
37              int sum1,sum2,sum3;
38              sum1 = sum2 = sum3 = 0;
39              for( int j=0;j<a[i].m;j++ ){
40                  scanf(" %c:%lf",&name,&tt);
41                  sum = (int)(tt*100.0);
42                  if( name<'A'||name>'C' ) a[i].vis = false;
43                  if( name=='A' ) sum1 += sum;
44                  if( name=='B' ) sum2 += sum;
45                  if( name=='C' ) sum3 += sum;
46                  if( sum1>60000||sum2>60000||sum3>60000 ) a[i].vis = false;
47              }
48              if( sum>100000 ) a[i].vis = false;
49              if( a[i].vis==true ) a[i].sum = sum1+sum2+sum3;
50              else a[i].sum = 0;
51          }
52          memset( dp,0,sizeof( dp ) );
53          int res = 0;
54          for( int i=0;i<n;i++ ){
55              for( int k=V;k>=a[i].sum;k-- ){
56                  dp[ k ] = max( dp[k],dp[k-a[i].sum]+a[i].sum );
57                  res = max( res,dp[k] );
58              }
59          }
60          printf("%.2lf\n",(double)res/100.0);
61     }
62     return 0;
63 }

 

 

这是一开始wa的代码。。。

View Code
 1 /*
 2 dp类似背包
 3 */
 4 #include<stdio.h>
 5 #include<string.h>
 6 #include<stdlib.h>
 7 #include<algorithm>
 8 #include<iostream>
 9 #include<queue>
10 #include<map>
11 #include<math.h>
12 using namespace std;
13 typedef long long ll;
14 //typedef __int64 int64;
15 const int maxn = 105;
16 const int inf = 0x7fffffff;
17 const double pi=acos(-1.0);
18 const double eps = 1e-8;
19 
20 struct node{
21     int vis;
22     int m;
23     int sum;
24     //int p[ 2005 ];
25 }a[ 36 ];
26 int dp[ 5000005 ];
27 
28 int main(){
29     int V,n;
30     double tt;
31     char name;
32     while( scanf("%lf%d",&tt,&n)==2 ){
33         if( n==0 ) break;
34          V = tt*100;
35          for( int i=0;i<n;i++ ){
36              scanf("%d",&a[i].m);
37              a[i].vis = true;
38              double sum = 0;
39              for( int j=0;j<a[i].m;j++ ){
40                  scanf(" %c:%lf",&name,&tt);
41                  sum += tt;
42                  //a[i].p[j] = tt*100;
43                  if( tt>600.0||name<'A'||name>'C'||sum>1000.0 ) a[i].vis = false;
44                  //if( name<'A'||name>'C' ) a[i].p[j] = 0;
45              }
46              if( a[i].vis==true ) a[i].sum = sum*100;
47              else a[i].sum = 0;
48          }
49          memset( dp,0,sizeof( dp ) );
50          int res = 0;
51          for( int i=0;i<n;i++ ){
52              //if( a[i].vis==true ){
53                  //for( int j=0;j<a[i].m;j++ ){
54                      for( int k=V;k>=a[i].sum;k-- ){
55                          dp[ k ] = max( dp[k],dp[k-a[i].sum]+a[i].sum );
56                          res = max( res,dp[k] );
57                      }
58                  //}
59              }
60              //else dp[ k ] = max( dp[k],dp[k-a[i].sum]+a[i].sum );
61          //}
62          printf("%.2lf\n",res/100.0);
63     }
64     return 0;
65 }

 

posted @ 2013-05-09 18:30  xxx0624  阅读(285)  评论(0编辑  收藏  举报