poj1416

本文介绍了一道使用C++解决的数位DP题目,通过递归深度优先搜索(DFS)实现,针对输入的目标值和数据编号进行处理,旨在找出最佳组合方案,使结果最接近目标值。代码中详细展示了数据切割、存储及回溯过程,适用于理解数位DP算法原理及其应用。
#include<iostream>
using namespace std;

int target,datanum;
int road[100],temproad[100];
int N,flag,maxsum;
int data[100],datatemp[100];
int tail;

void cun(int n)
{
    tail=0;
    
    while(n/10)
    {
        int m=n%10;
        n=n/10;
        datatemp[tail++]=m;
    }
    datatemp[tail++]=n%10;
    for(int i=0;i<tail;i++)
        data[i]=datatemp[tail-i-1];
    return;
}

void dfs(int n, int step, int sum, int tobe)
{
    if(sum>target)
        return;

    if(n==N-1)
    {
        sum=sum+tobe*10+data[N-1];
        temproad[step]=tobe*10+data[N-1];
        if(sum>target)
            return;
        if(sum==maxsum)
            flag=1;
        else if(sum>maxsum)
        {
            for(int i=0;i<100;i++)
                road[i]=-1;
            flag=0;
            maxsum=sum;
            for(int i=0;i<=step;i++)
                road[i]=temproad[i];
        }
        return;
    }

    temproad[step]=tobe*10+data[n];
    dfs(n+1,step+1,sum+tobe*10+data[n],0);//
    temproad[step]=-1;

    dfs(n+1,step,sum,tobe*10+data[n]);
}

int main()
{
    //freopen("input.txt","r",stdin);
    while(1)
    {
        cin>>target>>datanum;
        //cout<<target<<alldata<<endl;
        if(target==0&&datanum==0)
            break;
        if(target==datanum)
        {
            cout<<target<<' '<<target<<endl;
            continue;
        }
        for(int i=0;i<100;i++)
            data[i]=-1;
        cun(datanum);
        N=tail;
    
        maxsum=-1;
        flag=0;
        for(int i=0;i<100;i++)
        {
            road[i]=-1;
            temproad[i]=-1;
        }
        dfs(0,0,0,0);
        if(maxsum==-1)
            cout<<"error"<<endl;
        else if(flag==1)
            cout<<"rejected"<<endl;
        else
        {
            cout<<maxsum<<' ';
            for(int i=0;i<100;i++)
            {
                if(road[i]!=-1)
                    cout<<road[i]<<' ';
            }
             cout<<endl;
        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/bbcai/p/6811228.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值