SDIBTOJ1350-最小重量机器设计问题

来源:互联网 发布:刷信誉源码 编辑:程序博客网 时间:2024/06/08 10:53

题目链接:http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=1350
题目描述:给出n个部件在m个商家的价格,及其制造的重量,求在不大于给定价格d下,最小的重量。
题意分析:很经典的深搜回溯。我加了几组还算强大的测试数据,下列代码中的几个剪枝必须有哦,才能在OJ通过。否则,嘿嘿,等着TLE吧。

代码如下:


#include
 
#define INF 999999999
 
int w[22][22];   //存重量
int c[22][22];   //存价格
int v[22];   //存搜索过程中部件的制造商
int s[22];   //存符合条件的最优重量部件的制造商编号
int m, n, d;
int min, minw, maxc;
 
void DFS( int t, int p, int cnt ){
    int i;
    if( t > n){
       if( cnt < min ){
           min = cnt;
           for( int i=1; i<=m; i++ )
               s[i] = v[i];
       }
       return ;
   }
   //当前重量值已经比最小重量值大了,或者现有价格>给定价格,就没有必要继续了   
    if( cnt >min || d < p ){  
       return ;
    }
    for( i=1;i<=m; i++ ){
       if( d >= p + c[t][i] ){
           v[t] = i;
           DFS( t+1, p+c[t][i], cnt+w[t][i] );
       }
    }
}
 
int main(){
    int i,j;
    int tmp,r;
    while(scanf( "%d%d%d", &n, &m, &d ) != EOF ){
       maxc = minw = 0;
       for( i=1; i<=n; i++ ){
           for( j=1; j<=m; j++ ){
               scanf( "%d", &c[i][j] );
               if( j == 1 ) { tmp = c[i][j]; }
               else if( tmp < c[i][j] )  { tmp = c[i][j];}
           }
           maxc += tmp;
       }
       for( i=1; i<=n; i++ ){
           for( j=1; j<=m; j++ ){
               scanf( "%d", &w[i][j] );
               if( j == 1 ) { tmp = c[i][j]; r = j; }
               else if( tmp > c[i][j] )  { tmp = c[i][j]; r =j; }
           }
           minw += tmp;
           s[i] = r;
       }
 //此处是一个灰常经典的剪枝,如果一开始最大的价格都要比给定的价格小,那么可以直接输出最小值,预处理判断也是搜索剪枝当中非常重要的一个方法。
       if( maxc < d ){   
           printf( "%d\n", minw );
           for( i=1; i
               printf( "%d ", s[i] );
           printf( "%d", s[i] );
           continue;
       }
       min = INF;
       DFS( 1, 0, 0 );
       printf( "%d\n", min );
       for( i=1; i
           printf( "%d ", s[i] );
       printf( "%d", s[i] );
    }
    return0;
}