A Miser Boss

Time Limit: 2 Seconds Memory Limit: 65536 KB

There are three different lathes in a factory namely A,B,C. They are all able to work on all kinds of workpieces. And there aren workpieces to be processed, denoted by 1,2,..,n.

Due to different internal implemetations, for a specific workpiece i, it costs Aa[i] seconds to finish the job on it while B takes b[i] and C takesc[i] seconds. Each lathe can work on at most one workpiece a time.

Additionally, the Boss is so stingy that he didn't want his lathes to be disengaged at any time before the end of the work. That is:
1. there should not be a time when one of the lathes is in leisure.
2. all lathes should stop simultaneously,and start from time 0.

Your task is to find if there exists an arrangement meeting with the constraints above. if there is,output the minimal time needed to process all the workpieces. Output a lineNO else.

Input

There are multiple test cases. The first line of each case is an integer N(0 < N ≤ 40 ), followed by N lines. In the following N lines, line i contains three integer,a[i],b[i],c[i] (0 < a[i],b[i],c[i] ≤ 120 && 0 < sum(a[i]),sum(b[i]),sum(c[i]) ≤ 120 ) indicating the seconds A,B,C takes to process workpiecei.

Output

Output one line the minimal seconds it takes to process all workpieces within the constraints if there is an arrangement. PrintNO if not.

Sample Input

3
7 1 2
1 7 1
1 3 7
2
1 2 3
3 2 1

Sample Output

1
NO
 
代码转自一个叫 路竹 的人,该作者的网易博客名字叫 留得累人身外物,半肩行李半肩书
连接为http://pictureyong.blog.163.com/blog/static/851870682011102102720520/
 

感觉穷举的话需要有3的40次方的复杂度。 文章中说摒弃不必要的枚举,这一句不必要,我费死劲了才看懂。 应该是完成了第k个任务,a,b,c机器用的时间分别是an,bn,cn,那么不管任务是怎么分配的,效果是一样的。所以入队列时,这样的重复就都摒弃了。那么队列最大时也超不过120的3次方,时间复杂度同样不会超过这个。这个复杂度分析的好像没有多大意义。算了,就这样吧。

 

枚举用的是bfs,vis三位数组应该是dp,不过感觉不到dp的存在。

 
//思路:BFS枚举所有可能的生产方案,vis[][][]做优化摒弃不必要的枚举。
//代码:

#include<cstdio>
#include<cstring>
#include<queue>

#define INF_MAX 0xfffff
#define SIZE_N 42
#define MAX_N 122

using namespace std;

typedef struct{
    int an,bn,cn;//an:A机器的耗时,bn:B机器的耗时,cn:C机器的耗时
    int tn;//完成前 tn 个
}SNode;

int vis[MAX_N][MAX_N][MAX_N];//vis[i][j][k] = n;完成第 n 个零件后,A耗时 i,B耗时 j,C耗时 k 
int as[SIZE_N],bs[SIZE_N],cs[SIZE_N];

int BFS_DP(int n)
{
    int an,bn,cn,nn,ans;
    queue<SNode>que;
    SNode cur,next;

    memset(vis,0,sizeof(vis));
    cur.an = cur.bn = cur.cn = cur.tn = 0;
    que.push(cur);
    ans = INF_MAX;
    while(!que.empty()) {
        cur = que.front();
        que.pop();
        an = cur.an;
        bn = cur.bn;
        cn = cur.cn;
        nn = cur.tn + 1;
        if(nn == n + 1) {
            if(an == bn && bn == cn && an < ans){
                ans = an;
            }
            continue;
        }
        if(vis[an+as[nn]][bn][cn] != nn) {
            vis[an+as[nn]][bn][cn] = nn;
            next.an = an + as[nn];
            next.bn = bn;
            next.cn = cn;
            next.tn = nn;
            que.push(next);
        }
        if(vis[an][bn+bs[nn]][cn] != nn) {
            vis[an][bn+bs[nn]][cn] = nn;
            next.an = an;
            next.bn = bn + bs[nn];
            next.cn = cn;
            next.tn = nn;
            que.push(next);
        }
        if(vis[an][bn][cn+cs[nn]] != nn) {
            vis[an][bn][cn+cs[nn]] = nn;
            next.an = an;
            next.bn = bn;
            next.cn = cn + cs[nn];
            next.tn = nn;
            que.push(next);
        }
    }
    return ans;
}

int main()
{
    int n,i,ans;

    while(scanf("%d",&n) != EOF) {
        for(i = 1;i <= n;i ++) {
            scanf("%d%d%d",&as[i],&bs[i],&cs[i]);
        }

        if(n < 3) {puts("NO");continue;}
        ans = BFS_DP(n);
        if(ans == INF_MAX)
            puts("NO");
        else printf("%d\n",ans);
    }
    return 0;
}

posted on 2011-11-15 20:20  ConfuciusPei  阅读(141)  评论(0编辑  收藏  举报