2009年12月25日

          TopCoder SRM 403 Level2 1000
          4和7是幸運(yùn)數(shù)字,如果一個(gè)數(shù)只包含4和7,那么這個(gè)數(shù)字也是一個(gè)幸運(yùn)數(shù)字
          給定一個(gè)1-1,000,000的數(shù)字,求這個(gè)數(shù)字是否可以僅由幸運(yùn)數(shù)字相加得出,返回所有的幸運(yùn)數(shù)字加數(shù),如果有多組解,返回加數(shù)最少的一組

          以前沒有遇到過這樣的DP題目
          這題加深了我對(duì)于“每個(gè)子問題的答案都是最佳答案”的理解
          首先是額外的計(jì)算
          將范圍以內(nèi)的幸運(yùn)數(shù)字打表
          然后從輸入數(shù)字N開始遞減DP計(jì)算
          N的步數(shù)為0
          如果最后0的步數(shù)為正數(shù)
          說明有解
          再從0開始遞增尋找解的路徑

          不過這個(gè)方法最后也沒有通過tc的系統(tǒng)測(cè)試
          數(shù)字一大就超時(shí)了
          后面又時(shí)間再研究一下
          看看有沒有辦法在改進(jìn)

           1 import java.util.*;
           2 import java.util.regex.*;
           3 import java.text.*;
           4 import java.math.*;
           5 import java.awt.geom.*;
           6 
           7 public class TheSumOfLuckyNumbers
           8 {
           9     
          10     public int[] sum(int n)
          11     {
          12         ArrayList<Integer> table = calTable();
          13         int[] dp = new int[n+1];
          14         Arrays.fill(dp, Integer.MAX_VALUE-10);
          15         dp[n] = 0;
          16         int i , j;
          17         for(i = n; i > 0 ; -- i){
          18             for(int lucky:table){
          19                 if(i - lucky >=0 && dp[i] + 1 < dp[i - lucky])
          20                     dp[i - lucky] = dp[i] + 1;
          21             }
          22         }
          23         if(dp[0== Integer.MAX_VALUE)
          24             return new int[0];
          25         ArrayList<Integer> ans = new ArrayList<Integer>();
          26         int total = dp[0]-1;
          27         for(i = 0 ; i <= n; ++ i){
          28             for(int lucky:table){
          29                 if(i + lucky <= n && dp[i + lucky] == total){
          30                     ans.add(lucky);
          31                     i += lucky-1;
          32                     total--;
          33                     break;
          34                 }
          35             }
          36         }
          37         int[] ret = new int[ans.size()];
          38         for(i = 0 ; i < ans.size(); ++ i)
          39             ret[i] = ans.get(i);
          40         return ret;
          41     }
          42     
          43 
          44     
          45     public ArrayList<Integer> calTable(){
          46         ArrayList<Integer> table = new ArrayList<Integer>();
          47         table.add(4);
          48         table.add(7);
          49         int i = 1;
          50         while(i < 7){
          51             ArrayList<Integer> temp = new ArrayList<Integer>();
          52             for(int j = 0 ; j < table.size(); ++ j){
          53                 int newItem = table.get(j) * 10;
          54                 
          55                 temp.add(newItem+4);
          56                 temp.add(newItem+7);
          57             }
          58             i++;
          59             table.addAll(temp);
          60         }
          61         return table;
          62     }
          63 }


          posted @ 2009-12-25 16:13 jav7er 閱讀(167) | 評(píng)論 (0)編輯 收藏
           
          TopCoder SRM 405 Level 2 1000
          一個(gè)理想的字符串,其中每個(gè)字母第一次出現(xiàn)的位置N,與這個(gè)字母在字符串中出現(xiàn)的次數(shù)M是相等的,求給定長度的字符串中最小的一個(gè)理想字符串

          字符串長度小于100
          相當(dāng)于去搜索1~100中的一組不同的數(shù)
          加起來等于長度L
          同時(shí)每個(gè)數(shù)字都要小于等于比自己小的所有數(shù)的和加一
          因?yàn)長比較小
          所以用深搜就可以了
          在這個(gè)過程中要注意深搜時(shí)候需要從大往小搜
          這樣才能滿足“最小的”結(jié)果
          搜索完之后的字符串構(gòu)建的步驟因?yàn)镾tringBuffer用的不熟練
          反而調(diào)試了很久
           1 import java.util.*;
           2 import java.util.regex.*;
           3 import java.text.*;
           4 import java.math.*;
           5 import java.awt.geom.*;
           6 
           7 public class IdealString
           8 {
           9     int[] table = new int[26];
          10     int finalindex = 0;
          11     int L;
          12     
          13     public String construct(int length)
          14     {
          15         Arrays.fill(table, 0);
          16         L = length;
          17         if(dfs(100)){
          18             StringBuffer sb = new StringBuffer();
          19             char c = 'A';
          20             int i , j = 0;
          21             for(i = 0 ; i < L; ++ i)
          22                 sb.append(' ');
          23             for(i = 0 ; i < finalindex; ++i){
          24                 sb.setCharAt(table[i] - 1, c ++);
          25                 table[i]--;
          26             }
          27             for(i = 0 ; i < L; ++ i){
          28                 if(sb.charAt(i) != ' ')
          29                     continue;
          30                 while(table[j] == 0) j++;
          31                 sb.setCharAt(i, (char)('A' + j));
          32                 table[j]--;
          33             }
          34             return sb.toString();
          35         }
          36         return new String();
          37     }
          38     
          39     boolean dfs(int num, int index, int sum){
          40         table[index] = num;
          41         int base = num + sum;
          42         if(base == L){
          43             table[index] = num;
          44             finalindex = index + 1;
          45             return true;
          46         }
          47         if(base > L)
          48             return false;
          49         int total = 0;
          50         for(int i = 0 ; i <= index ; ++ i)
          51             total += table[i];
          52         for(int i = total + 1;  i >= num + 1-- i){            
          53             if(base + i <= L && dfs(i, index +1, base))
          54                 return true;
          55         }
          56         return false;
          57     }
          58 }


          posted @ 2009-12-25 16:00 jav7er 閱讀(143) | 評(píng)論 (0)編輯 收藏
           
          主站蜘蛛池模板: 阳山县| 鄂伦春自治旗| 永顺县| 寿宁县| 夹江县| 乐昌市| 安陆市| 兴山县| 沭阳县| 隆子县| 阜阳市| 高雄市| 徐汇区| 曲靖市| 永胜县| 潞西市| 光泽县| 原阳县| 普安县| 六盘水市| 武功县| 叶城县| 鸡西市| 巢湖市| 安远县| 万年县| 磐石市| 清徐县| 正安县| 南召县| 棋牌| 青海省| 兖州市| 濉溪县| 元江| 分宜县| 玛纳斯县| 河南省| 广河县| 政和县| 余庆县|