随笔-20  评论-16  文章-36  trackbacks-0

         题目大意:给一个总和t与n个数,打印出用这n个数组合出和为t的所有情况,当然不能有重复情况。
         感觉像这类题目都可以转化成k进制的问题,拿这题来说,可以转换成一个复杂的(a1,a2,a3..an)进制的问题,其中ai为第i位的进制。由于题目中n很小,因此转化后的规模很小。
         具体的说,用emt[l]{int key,num;}来记录有哪些数及它们的个数,用a[n]来表示一个(a1,a2,a3..an)进制的数,初始化为最大,即a[i]=emt[i].num,则要做的是递减a[n],每次计算对应的和Sa[i]*emt[i].key,如果为t则打印组合。
         当然,可以采用数据压缩技术和剪枝判断来减小计算量和判断提前结束,但这题的规模很小,优化没什么意义,已经是0ms了。下面是主要代码:

struct Emt{
    
int key;
    
int num;
}
emt[13];
int a[13], l;
//递减函数,如果减为负数,则返回false,否则返回true
bool Dec(){
    
forint i= l ;i>= 0; i-- ){
        a[i]
--;
        
if( a[i]<0 && i>0 )
            a[i]
= emt[i].num;
        
else
            
break;
    }

    
return ( a[0]>= 0 );
}

//判断是否是正确的组合
sus= false;
while( Dec() ){
    cur
= 0;
    
for( i= 0; i<= l; i++ )
        cur
+= a[i]*emt[i].key;
    
if( cur==t ){
        Print();
        sus
= true;
    }

}

if!sus )    puts("NONE");
posted on 2009-04-13 18:12 古月残辉 阅读(428) 评论(0)  编辑 收藏 引用 所属分类: POJ

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理