【DFS】poj 1416 Shredding Company

题目描述:

http://poj.org/problem?id=1416

 

中文大意:

要求编写一个碎纸机程序。

待碎纸张上仅包含数字,切割后,每个碎片上也都会有一个或多个数字。

给定一个目标数字,要求所有碎纸上的数字之和尽可能地接近目标数字,但不能越过该数字。

还有三个特殊规则:

1.如果目标数字与纸张上的数字相同,则不用裁切。

2.如果无解,则输出“error”。

3.如果最接近目标数字的解有多种可能,则输出“rejected”。

 

思路:

假设待碎纸张上有 N 个数字,尝试从最左端开始,切一定数量的数字。

一共有 N 种切法:切 1 个数字,切 2 个数字......

剩余纸张,继续以这种方法切割,直至切割完成。

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<sstream>
using namespace std;

int t,num; 
int parts[6];//各碎片的数值大小 
bool results;//是否有多组解 

int end_sum,end_k;//用来记录最优数据
int end_parts[6];

//str:未粉碎部分 
//k:当前碎片个数 
void dfs(string str, int k){
    //纸片粉碎完成 
    if(str.length() == 0){
        //计算所有碎片之和 
        int sum = 0;
        for(int i=0;i<k;i++){
            sum += parts[i];
        }
        
        //题目要求 sum 应 <= t 
        if(sum <= t){
            //已经有了满足条件的一组解
            if(sum == end_sum){    
                results = true;
            }
            else if(sum > end_sum){//更优解 
                end_sum = sum;
                for(int i=0;i<k;i++){
                    end_parts[i] = parts[i];
                }
                end_k = k;
                results = false;
            }
        }
        return;
    }
    
    //p1:已切割部分 
    //p2:剩余部分 
    string p1,p2;
    //尝试切割 i个数字 
    for(int i=1;i<=str.length();i++){ 
        p1 = str.substr(0,i);
        //纸条还有剩余 
        if(i != str.length()){
            p2 = str.substr(i);
        }
        else{//切割全部,没有剩余 
            p2 = "";
        }
        
        //string -> int 
        istringstream iss(p1);
        iss >> parts[k];
        
        //继续切割剩余部分 
        dfs(p2, k+1);
    }
}

int main(){
    while(scanf("%d %d", &t, &num) && (t || num)){
        end_sum = -1;
        results = false;
        
        //int -> string 
        ostringstream oss;
        oss << num;
        
        dfs(oss.str(), 0);
        
        if(results){
            printf("rejected
");
        }
        else if(end_sum == -1){
            printf("error
");
        }
        else{
            printf("%d", end_sum);
            for(int i=0;i<end_k;i++){
                printf(" %d", end_parts[i]);
            }
            printf("
");
        }
    }
}
作者:老干妈就泡面
本文版权归作者和博客园共有,欢迎转载,但请给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/bjxqmy/p/14449329.html