zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    11. Container With Most Water
    9. Palindrome Number
    375. 猜数字大小 II leetcode java
    leetcode 72 编辑距离 JAVA
    73. 矩阵置零 leetcode JAVA
    快速排序 JAVA实现
    63. 不同路径 II leetcode JAVA
    重写(override)与重载(overload)
    62 不同路径 leetcode JAVA
    leetcode 56 合并区间 JAVA
  • 原文地址:https://www.cnblogs.com/wsy107316/p/13499286.html
Copyright © 2011-2022 走看看