[2016-03-07][UVALive][4292][Matchsticks]

[2016-03-07][UVALive][4292][Matchsticks]


  • 时间:2016-03-06 14:15:55 星期日
  • 题目编号:[UVALive][4292][Matchsticks] F - F
  • 题目大意:给定若干跟火柴,求这些火柴能拼成的最大的数字和最小的数字
  • 输入:数据组数c
      • 每组数据一个整数,表示火柴数目
  • 输出:最小数字和最大数字
  • 方法:
      • 方法1:贪心,最大位数,如果数目是偶数,直接111111...,如果是奇数就是711111...
          • 最小位数,贪心,大于16位的,一定是选择8,否则的话,会位数会多,小于16的部分,分类讨论
      • 方法2:最大值还是一样,
          • 最小值,先dfs一遍,得到最小位数,然后IDA*枚举每一位上的数字,得到最小值
      • 方法3:最大值一样
          • 最小值dp dp[i]表示i根火柴的能表示的最小值,a[k]表示第k个数字消耗的火柴,dp[i] = min(dp[i],dp[i - a[k]] + k);
  • 解题过程遇到问题:
      • Min声明的时候数组只开了11(之前是为了计算每个数字的次数,后来改了,忘记增加),WA了
        • (然后之前也弄了Max对最大值的每一位计数,没删除,因为Min和Max连在一起,当时没WA,整理代码的时候,删除了Max,就WA了)
      • dp的时候,数值是可以超过int的范围的,然后改成LL之和,各种连带错误(输出,初始化)忘记改


//IDA*
#ifdef _WORK_
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef long long LL;
#define CLR(x,y) memset((x),(y),sizeof((x)))
#define FOR(x,y,z) for(int (x)=(y);(x)<(z);++(x))
#define FORD(x,y,z) for(int (x)=(y);(x)>=(z);--(x))
#define FOR2(x,y,z) for((x)=(y);(x)<(z);++(x))
#define FORD2(x,y,z) for((x)=(y);(x)>=(z);--(x))



int cost[] = {6,2,5,5,4,5,6,3,7,6};
//            0,1,2,3,4,5,6,7,8,9
int n,Min[110],minct;//最小位数
int dfs(int left,int ct){
        if(left == 0){   
                minct = ct;
                return 1;
        }
        FORD(i,7,2){
                if(left >= i && dfs(left - i,ct + 1)){
                        return 1;
                }
        }  
        return 0;
}
int dfsmin(int left,int cur){
        if(cur == minct){
               return   left == 0;
        }
        //IDA* 剪个枝,不然会T
        if(left + 7*cur > 7*minct)      return 0;
        if(cur && left >= cost[0]){
                if(dfsmin( left - cost[0],cur + 1 )){
                        Min[cur] = 0;
                        return 1;
                }
        }
        FOR(i,1,10){
              if(left >= cost[i]){
                        if(dfsmin( left - cost[i],cur + 1)){
                                Min[cur] = i;
                                return 1;
                        }
              }
        }  
        return 0;
}
int main(){
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int T;
        scanf("%d",&T);
        while (T--){
                scanf("%d",&n);
                dfs(n,0);//求最少位数
                dfsmin(n,0);//求最少位数下最小的答案
                FOR(i,0,minct)  putchar('0' + Min[i]);
                putchar(' ');
                if(n&1){
                        putchar('7');
                        n -= 3;
                }
                FOR(i,0,n/2)    putchar('1');
                putchar('\n');
        }
        return 0;
}
#endif  

//dp
#ifdef _WORK_
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef long long LL;
#define CLR(x,y) memset((x),(y),sizeof((x)))
#define FOR(x,y,z) for(int (x)=(y);(x)<(z);++(x))
#define FORD(x,y,z) for(int (x)=(y);(x)>=(z);--(x))
#define FOR2(x,y,z) int (x);for((x)=(y);(x)<(z);++(x))
#define FORD2(x,y,z) int (x);for((x)=(y);(x)>=(z);--(x))



int n,a[] = {6,2,5,5,4,5,6,3,7,6};
LL dp[110] = {0x3f3f3f3f,0x3f3f3f3f,1,7,4,2,6,8,};
void inidp(){
        memset(dp+8,0x7f,sizeof(LL)*(100));
        FOR(i,8,101){
                FOR(j,0,10){
                     dp[i] = min(dp[i],dp[i - a[j]]*10 + j);   
                } 
        }
}
int main(){
        //freopen("out.txt","w",stdout);
        inidp();
        int T;      
        scanf("%d",&T);
        while (T--){
                scanf("%d",&n);              
                printf("%lld ",dp[n]);
                if(n&1){
                        putchar('7');
                        n -= 3;
                }
                FOR(i,0,n/2)    putchar('1');
                putchar('\n');
        }
    return 0;
}
#endif  



来自为知笔记(Wiz)


posted on 2016-03-07 19:53  红洋  阅读(176)  评论(0)    收藏  举报

导航