HDU1864+dp+类似背包
和以前的背包方程有点不同。
注意:一张支票上可能有多个可能相同的项目
这是AC的代码。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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代码。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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的代码。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
keep moving...