HDU6831 Fragrant numbers(区间dp)

这题直觉上来说可以使用区间dp进行合法状态的转移,然后记录最小值。

现在的问题是这个是个无限长度的串,因此我们可以大胆猜测,只需要其中一部分就能把所有的情况构造出来

经过打表处理后发现,只需要前13个以内就能构造出所有合法状态,因此只需要这样区间dp即可

#include<bits/stdc++.h>
#define getsz(p) (p?p->sz:0)
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=3e5+10;
int f[14][14][5050];
string s="01145141919114514";
int st[N];
int ans[N];
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
        memset(f,0,sizeof f);
        int len,i,j,k;
        int tmp=0;
        for(i=1;i<13;i++){
            tmp=0;
            for(j=i;j<=(min(12,i+3));j++){
                tmp=tmp*10+(s[j]-'0');
                if(tmp<=5000)
                    f[i][j][tmp]=1;
            }
        }
        for(len=2;len<13;len++){
            for(i=1;i+len-1<13;i++){
                int j=i+len-1;
                for(k=i;k<j;k++){
                    for(int l=1;l<=5000;l++){
                        if(!f[i][k][l])
                            continue;
                        for(int r=1;r<=5000;r++){
                            if(!f[k+1][j][r])
                                continue;
                            if(l*r<=5000)
                                f[i][j][r*l]=1;
                            if(l+r<=5000)
                                f[i][j][l+r]=1;
                        }
                    }
                }
            }
        }
        for(i=1;i<=13;i++){
            for(j=1;j<=5000;j++){
                if(f[1][i][j]&&(!ans[j])){
                    ans[j]=i;
                }
            }
        }
    while(t--){
        int n;
        cin>>n;
        cout<<(ans[n]?ans[n]:-1)<<endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ctyakwf/p/13451551.html