poj 1416 Shredding Company (dfs)

鏈接:poj 1416

題意:有一種新的碎紙機,要用新的碎紙機將紙條上的數字切成幾部分,

      求切完後的和最接近而不超過target的值。

比如,target的值是50,而紙條上的數字是12346,應該把數字切成四部分,

分別是1、2、34、6。所得到的和43 (= 1 + 2 + 34 + 6) 是不超過50的最大和

比如1, 23, 4, 和6 ,和爲34,比43小,

而12, 34, 6不可以,因爲它們的和超過50了。

碎紙還有以下三個要求:

  1、如果target的值等於紙條上的值,則不能切。
  2、如果沒有辦法把紙條上的數字切成不超過target,則輸出error。

     如target是1而紙條上的數字是123,則無論你如何切得到的和都比1大。
  3、如果有一種以上的切法得到最佳值,則輸出rejected。

     如target爲15,紙條上的數字是111,則有以下兩種切法11、1或者1、11.

如果有且僅有一種最佳方案,則輸出最大值和切割的方案

思路:用dfs搜索每一種可能的情況,取不超過target的最大值,並記錄分割的方案


#include<stdio.h>
#include<string.h>
int ans,m,n,vis[1000000],step[10],now[10],num;
char s[10];
void dfs(int pos,int sum,int cnt)
{
    int i,t;
    if(pos>=m){
        vis[sum]++;
        if(sum>ans){
            ans=sum;  //記錄最佳切割的和
            num=cnt;
            for(i=0;i<cnt;i++) //記錄當前最佳方案
                step[i]=now[i];
        }
        return ;
    }
    t=0;
    for(i=pos;i<m;i++){
        t=t*10+s[i]-'0';
        if(sum+t>n)
            return ;
        now[cnt]=t;
        dfs(i+1,sum+t,cnt+1);
    }
}
int main()
{
    int i,sum;
    while(scanf("%d%s",&n,s)!=EOF){
        m=strlen(s);
        if(n==0&&s[0]=='0'&&m==1)
            break;
        sum=0;
        for(i=0;i<m;i++)
            sum+=s[i]-'0';
        if(sum>n){   //若最小的和都大於targe,則肯定不可能切割出不超過targe的和
            printf("error\n");
            continue;
        }
        memset(vis,0,sizeof(vis));
        num=ans=0;
        dfs(0,0,0);
        if(vis[ans]>1)
            printf("rejected\n");
        else{
            printf("%d",ans);
            for(i=0;i<num;i++)
                printf(" %d",step[i]);
            printf("\n");
        }
    }
    return 0;
}


發佈了152 篇原創文章 · 獲贊 7 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章