• Fragrant numbers(dfs爆搜+区间dp+stoi)


    Fragrant numbers(dfs爆搜+区间dp)

    题意:给出一个以 "1145141919 " 无限循环的字符串,可以在合适的位置添加 ' + ' , ' * ' 和 ' ( ' , ' ) ' 将其转换为表达式进行运算,给了一个n,问最少需要前几个字符来构成n?

    题解:(dfs)爆搜+区间dp:(dp[l][r])记录字符串(l)到(r)之间可以产生的数,用(set)类型来自动去重,具体见代码:

    AC_Code:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef long double ld;
     5 #define endl '
    '
     6 const int inf=0x3f3f3f3f;
     7 const int maxn=1e5+10;
     8 
     9 
    10 string st=" 11451419191145141919";  //注意前面一个空格,因为我们区间的下标是从1开始的
    11 int ans[maxn];
    12 set<int>dp[20][20];
    13 
    14 void dfs(int l,int r){
    15     if( dp[l][r].size() ) return ;  //dp[l][r].size()不为0说明已经存入了数据了
    16     int len=r-l+1;
    17     if( len<=4 ){   //如果大于4了就一定大于题目所给的5000了必须拆开,小于等于4可以不用拆开
    18         int num=stoi(st.substr(l,r-l+1));//stoi:把字符串化成十进制
    19         if( num<=5000 ) dp[l][r].insert(num);
    20     }
    21     for(int i=l;i<r;i++){
    22         dfs(l,i);
    23         dfs(i+1,r);
    24         for(int x:dp[l][i]){
    25             for(int y:dp[i+1][r]){
    26                 if( x+y<=5000 ) dp[l][r].insert(x+y);
    27                 if( x*y<=5000 ) dp[l][r].insert(x*y);
    28             }
    29         }
    30     }
    31 }
    32 
    33 void init(){
    34     memset(ans,-1,sizeof(ans));
    35     for(int i=1;i<=11;i++){
    36         dfs(1,i);
    37         for(int x:dp[1][i]){
    38             if( ans[x]==-1 ) ans[x]=i;
    39         }
    40     }
    41 }
    42 
    43 set<int>num;
    44 int main()
    45 {
    46     init();
    47 //  注释掉的部分遍历一下发现前11位就可以到5000了dfs完全可以AC,如果前11位都组不成的数字,以后跟不可能了,因为只有加法和乘法数字只会变大了
    48 //    for(int i=1;i<=11;i++){
    49 //        for(int x:dp[1][i] ){
    50 //            num.insert(x);
    51 //        }
    52 //    }
    53 //
    54 //    for( auto &x:num){
    55 //        cout<<x<<endl;
    56 //    }
    57 
    58     int T; cin>>T;
    59     while( T-- ){
    60         int n; cin>>n;
    61         cout<<ans[n]<<endl;
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    POJ2155 Matrix 【二维线段树】
    BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】
    B1027 打印沙漏
    Tomcat无法成功启动——双击startup.bat闪退
    MySQL在cmd命令行查看端口号
    1009 说反话(类似回文字符串)
    除基取余法,
    日期差值
    怎么把VS里的scanf_s换成scanf
    联想小新潮怎么修改fn热键以及怎么进入bios状态
  • 原文地址:https://www.cnblogs.com/wsy107316/p/13499286.html
Copyright © 2020-2023  润新知