人搜一道笔试题的解

题目:

有N个节点,每两个节点相邻,每个节点只与2个节点相邻,因此,N个顶点有N-1条边。每一条边上都有权值wi,定义节点i到节点i+1的边为wi。
求:不相邻的权值和最大的边的集合。

思路:典型的分治算法,使用递归方式来逐步缩小问题范围,最终找到返回条件:如果当前位置没有下一个相隔位置(为倒数第1个或倒数第2个位置),那么就返回当前位置的值。如果存在下一个相隔位置,那么缩小问题规模,把当前位置的值和合法位置的值逐个相加,在合法位置集合中找到和当前位置值相加后最大的值返回。

代码:

#include <stdio.h>

int perm(int list[], int k, int m) 
{     
    int i;
    int max=0;
    if(k == m-1)     
    {          
        return list[k];  //如果是倒数第2个位置,那么返回当前位置值
    }
    else if (k >= m)
    {
        return list[m]; //如果是倒数第1个位置,那么返回当前位置值
    }
    else     
    {         
        for(i = k; i < m-1; i++)         
        {             
            int x=list[k]+perm(list,i+2,m);//当前位置和下一个合法位置(i+2)最大值相加
            if (x>max)
            {
                max=x; //找到当前位置和所有合法位置最大值相加最大的值
            }
        }     
        return max;
    } 
} 
int main() 
{     
    int list1[] = {1, 1, 1, 10, 1, 1, 7, 1, 1}; 
    int list2[] = {2, 3, 7, 5, 1, 8};
    int size=(sizeof(list1)/sizeof(int))-1;
    printf("total:%d\n", perm(list1, 0, size));     
    return 0; 
}  

转载于:https://www.cnblogs.com/darknightsnow/archive/2012/09/27/2705561.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值