zoj 1937 || poj 2248 Addition Chains

    技术2026-09-28  4

    昨晚看的这个题,今天早上上课的时候,想起来了,就想了下,机组老师太能喷了,基本都在说了,不过确实有的挺有道理的。

     

    第二节英语课,我快郁闷死了,老师说,这节课第一节,就不讲了,结果我们愣了两节课。。。就带了英语书和机组书,不想看 = =。。

     

    中午把这题给A掉了,嘻嘻。

     

    这题是,给你数n,求出1......n 一串数,其中每个数字分解的两个加数都在这个序列中(除了1,两个加数可以相同),要求这个序列最短。

     

    上机组的时候,就想了想,在纸上画了画,决定用BFS。

     

    首先,BFS是一层一层往下搜的,则最先搜到的一定是最短的,所以最先搜到就可以保存了啦,所以打个表。。。就好了。

     

    中间可能有点问题,如果搜到的比当前的短,把当前的覆盖掉,换成短的。

     

    77那个数据,我的是10个,换成覆盖掉就9个了,很奇怪啊。

     

    得上课了。。。

     

    恩,上完了,老师太能说了,呵呵,跟我想象出入很大,是个年轻老师,不过人家说的都挺在理的。

     

    恩。。可是,这个不是一层一层扩展的么,应该是逐步加深的啊,这个杂还还会少呢,我很费解啊。

     

    党用的是迭代加深DFS神马的,恩。。我不会那个。。。

     

    恩。想明白了。因为如果不是取最小的话,那么后面有些枝直接被截掉了,或许后面有机会更早到达77也被砍掉了,所以不要砍掉,保存最小的那个。

     

     

    #include <cstdio> #include <cstdlib> #include <iostream> #include <string.h> #include <queue> #include <stack> #include <math.h> #include <algorithm> #include <limits.h> #define MAX 110 using namespace std; typedef struct MAP{ int out[MAX]; int len; }MAP; int n; int ans[MAX][MAX]; int l[MAX]; queue<MAP> q; void BFS() { int i,k; for(i=1; i<MAX; i++) l[i] = 5000; MAP a; a.len = 1; a.out[0] = 1; l[1] = 1; q.push(a); ans[1][0] = 1; while( !q.empty() ) { MAP tmp = q.front(); int out[MAX]; memcpy(out,tmp.out,sizeof(tmp.out)); q.pop(); for(i=0; i<tmp.len; i++) for(k=i; k<tmp.len; k++) if( tmp.len+1 <= l[out[i]+out[k]] && out[i] + out[k] < MAX ) { MAP b; memcpy(b.out,tmp.out,sizeof(tmp.out)); b.out[tmp.len] = out[i]+out[k]; memcpy(ans[out[i]+out[k]],b.out,sizeof(b.out)); b.len = tmp.len+1; l[out[i]+out[k]] = b.len; q.push(b); } } } int main() { int i,len; BFS(); while( ~scanf("%d",&n) && n ) { len = l[n]; printf("%d",ans[n][0]); for(i=1; i<len; i++) printf(" %d",ans[n][i]); printf("/n"); } return 0; }  

    最新回复(0)