今天已经是集训的第二天了,今天的考试主要考了区间DP,其实这一段我并不很熟。
其实这是我第二遍写这篇博客了,原来那篇被某邹姓少年弄没了,我只好再写一遍了。
PART ONE:DP复习二:
其实这道题在上午的时候我写出来了。只是我用的是暴搜,可能数据比较水就让我过了,但是其实这道题的正解我是不会写的,于是就在这里补一下吧,其实我感觉暴搜在DP这里的应用领域还是挺广的,包括昨天和今天好多题我都是用暴搜做的,还过了不少。但是从今天下午开始暴搜的应用就不怎么广了,好几道题都是只能得到一半左右的分数
方法一: 暴搜,用dfs的三个变量分别表示当前所处理到的位数,当前所分成的段数量及此时的乘积,暴搜的思路挺好想的,就是看数据,特别容易超时,所以最好慎用。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 const int N=5e1+10; 5 #define int long long 6 using namespace std; 7 int len,a[N],b[N],pos[N],dp[N][N],score[N][N],g[N][N]; 8 int ans2[N],t[N],Max=-1; 9 void dfs(int now,int m,int ans){ 10 if(now>len+1 || m<0) return; 11 if(now==len+1&&m==0){ 12 if(ans>Max){ 13 Max=ans; 14 for(int i=0;i<=t[0];++i) 15 ans2[i]=t[i]; 16 } 17 } 18 for(int i=now;i<=len;++i){ 19 t[++t[0]]=score[now][i]; 20 dfs(i+1,m-1,ans*score[now][i]); 21 t[0]--; 22 } 23 } 24 void Solve(){ 25 memset(dp,0,sizeof(dp)); 26 memset(score,0,sizeof(score)); 27 memset(g,0,sizeof(g)); 28 memset(t,0,sizeof(t)); 29 Max=-1; 30 len=0; 31 int num,m; 32 scanf("%lld%lld",&num,&m); 33 while(num){ 34 b[++len]=num%10; 35 num/=10; 36 } 37 for(int i=1;i<=len;++i) pos[len-i+1]=b[i]; 38 for(int i=1;i<=len;++i) 39 for(int j=i;j<=len;++j) 40 for(int k=i;k<=j;++k){ 41 score[i][j]*=10; 42 score[i][j]+=pos[k]; 43 g[i][i]=pos[i]; 44 } 45 dfs(1,m,1); 46 printf("%lld\n",Max); 47 for(int i=1;i<=ans2[0];++i) printf("%lld ",ans2[i]); 48 } 49 signed main(){ 50 int T; 51 scanf("%lld",&T); 52 while(T--) Solve(); 53 return 0; 54 }