我希望你是我独家记忆

一段永远封存的记忆,随风而去
posts - 263, comments - 31, trackbacks - 0, articles - 3
   :: 首页 :: 新随笔 ::  :: 聚合  :: 管理

P1717——标号法

Posted on 2008-09-10 19:02 Hero 阅读(178) 评论(0)  编辑 收藏 引用 所属分类: 代码如诗--ACM
 1 //1717 Accepted 272K 47MS C++ 1048B PKU
 2 
 3 //第一个标号法程序--不断更新当前能取得的组合数的最小翻转次数
 4 
 5 #include <stdio.h>
 6 #include <string.h>
 7 #include <stdlib.h>
 8 
 9 const int INF = 1e9 ;
10 const int size = 14000 ;
11 
12 int flag[size+100] ;
13 int inn ;
14 
15 void process()
16 {
17     flag[0= 0 ;
18     forint i=1; i<=size; i++ ) flag[i] = INF ;
19 
20     int inup, indn ; int sum = 0 ;
21 
22     forint i=1; i<=inn; i++ )
23     {
24         scanf( "%d %d"&inup, &indn ) ; sum += ( inup+indn ) ;
25         forint k=sum; k>=0; k-- )
26         {
27             if( flag[k] != INF  )//如果当前的值组合出来过
28             {
29                 int turns = flag[k] ;//得到当前组合数所需要的反转次数
30                 flag[k] = INF ;//由于要更新--当前组合数不存在了
31 
32                 //更新操作--如果下一个dn可以得到的值k+indn所需的次数比当前大--更新
33                 //以dn为基准--k+indn更新时不需要+1
34                 if( flag[k+indn] > turns )   flag[k+indn] = turns ;
35                 if( flag[k+inup] > turns+1 ) flag[k+inup] = turns+1 ;
36             }
37         }
38     }//标号法更新
39 
40     //从中间开始向两边搜寻down可以翻转最小次能够得到的值
41     int i, j ;
42     for( i=sum/2,j=sum/2.0+0.5; INF==flag[i]&&INF==flag[j]; i--,j++ ) ;
43 
44     printf( "%d\n", flag[i]<flag[j]? flag[i]:flag[j] ) ;
45 }
46 
47 int main()
48 {
49     while( scanf( "%d"&inn ) != EOF )
50     {
51         //input() ;
52 
53         process() ;
54 
55         //output() ;
56     }
57 
58     return 0 ;
59 }

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理