zoukankan      html  css  js  c++  java
  • 【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("
    ");
            }
        }
    }
    作者:老干妈就泡面
    本文版权归作者和博客园共有,欢迎转载,但请给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    Dos命令%date:~0,10%
    SharePoint显示错误信息
    VM打开虚拟机文件报错
    Sharepoint2013切换用户菜单
    批量创建域用户
    通过数据库恢复SharePoint网站
    SharePoint2013修复报错
    js 循环
    js 正则表达式
    阶乘函数
  • 原文地址:https://www.cnblogs.com/bjxqmy/p/14449329.html
Copyright © 2011-2022 走看看