CF 401D - Roman and Numbers

来源:互联网 发布:直播回看软件 编辑:程序博客网 时间:2024/05/01 14:40

开始用回溯做,不出意料的超时了。

网上找了别人的思路,用数位dp压缩使用状态i和余数j的情况数。

刚开始开头不能为0还处理不来...偷学了别人的代码。

#include<stdio.h>#include<iostream>#include<string.h>using namespace std;typedef long long LL;LL dp[1<<18][100];//使用状态i和余数j的情况数char n[20];LL bit[20],fac[20],m;int digit[10];int main(){bit[0]=1,fac[0]=1;for(int i=1;i<19;i++){bit[i]=bit[i-1]*2;//2的i次fac[i]=fac[i-1]*i;//i的阶乘}cin>>n>>m;int len=strlen(n);LL state=bit[len];for(int i=0;i<len;i++){//避免开头0int tmp=n[i]-'0';if(tmp)dp[bit[i]][tmp%m]=1;digit[tmp]++;}LL repeat=1;//重复次数for(int i=0;i<10;i++)repeat*=fac[digit[i]];for(LL s=0;s<state;s++){//状态for(int j=0;j<m;j++){//余数if(dp[s][j]==0) continue;for(int i=0;i<len;i++){//选择位if((s&bit[i])!=0) continue;//==1 wadp[s+bit[i]][(j*10+(n[i]-'0'))%m]+=dp[s][j];}}}printf("%I64d\n",dp[state-1][0]/repeat);return 0;}


0 0
原创粉丝点击