HDU 4352 XHXJ's LIS(数位dp)
来源:互联网 发布:国内外手游推荐知乎 编辑:程序博客网 时间:2024/05/29 09:16
题意:寻找 [L,R] 中满足条件的数的数量。条件:把一个数看成字符串,它的LIS若等于k,则满足条件。
题解:数位dp。
一开始的想法:考虑nlogn的LIS写法,因此状态包含一个长度为10的字符串,由0~9,inf组成。
但是需要把字符串映射成int,用到map,复杂度据说太高了。
正解:nlogn的LIS写法是维护了一个数组,由0~9,inf组成。那么对于本题,我们只要用一个二进制维护出现的数字即可。
#include<cstdio>#include<string>#include<map>#include<iostream>#include<cstring>using namespace std;typedef long long ll;int k;ll l,r;int dig[20];ll d[20][1024][11];int nxtsta(int sta,int x) {for(int i=x;i<=9;++i) {if((sta>>i)&1) return (sta^(1<<i))|(1<<x);}return sta|(1<<x);}ll dp(int po,int sta,bool zero,bool limit) {if(po==-1) {int cnt=0;while(sta) {if(sta&1) ++cnt;sta>>=1;}return cnt==k;}if(!zero&&!limit&&d[po][sta][k]!=-1) return d[po][sta][k];int to=limit?dig[po]:9;ll ans=0;for(int i=0;i<=to;++i) {ans=ans+dp(po-1,(zero&&i==0)?0:nxtsta(sta,i),zero&&i==0,limit&&i==to);}if(!zero&&!limit) d[po][sta][k]=ans;return ans;}ll solve(ll x) {int pos=0;while(x) {dig[pos++]=x%10;x/=10;}return dp(pos-1,0,1,1);}int main() {///initmemset(d,-1,sizeof(d));int T;scanf("%d",&T);int ca=0;while(T--) {printf("Case #%d: ",++ca);///readscanf("%lld%lld%d",&l,&r,&k);///solveprintf("%lld\n",solve(r)-solve(l-1));}return 0;}
//下面代码把自己一开始的想法贴出来,因为我感觉可能是我写丑了...不一定是复杂度的问题
#include<cstdio>#include<string>#include<map>#include<iostream>#include<cstring>using namespace std;typedef long long ll;string s[2000];map<string,int> id;ll l,r;int k,cnts;int dig[25];ll d[25][15][2000];ll dp(int po,int ids,bool zero,bool limit) {// cout<<po<<" "<<str<<" "<<endl; string str=s[ids]; if(po==-1) return (k==10||str[k]=='A')&&str[k-1]!='A'; if(!zero&&!limit&&d[po][k][id[str]]!=-1) return d[po][k][id[str]]; int to=limit?dig[po]:9; ll ans=0; for(int i=0;i<=to;++i) { string tmp=str; for(int j=0;j<=9;++j) { if(str[j]>='0'+i) { if(!(zero&&i==0)) tmp[j]='0'+i; break; } } if(tmp[k]!='A') continue; ans=ans+dp(po-1,id[tmp],zero&&i==0,limit&&i==to); } if(!zero&&!limit) d[po][k][id[str]]=ans; return ans; }ll solve(ll x) { int pos=0; while(x) { dig[pos++]=x%10; x/=10; } return dp(pos-1,1024,1,1);}void dfs(int po,int pre,string str) { if(po==10) { int len=str.length(); for(int i=len;i<=9;++i) str=str+'A'; s[++cnts]=str; id[str]=cnts; return ; } for(int i=pre+1;i<=9;++i) { char c='0'+i; dfs(po+1,i,str+c); } dfs(10,0,str);}int main() { ///init memset(d,-1,sizeof(d)); /// cnts=0; dfs(0,-1,""); int T;scanf("%d",&T); int ca=0; while(T--) { printf("Case #%d: ",++ca); ///read scanf("%lld%lld%d",&l,&r,&k); ///solve printf("%lld\n",solve(r)-solve(l-1)); } return 0;}
0 0
- 【HDU】4352 XHXJ's LIS 数位DP
- 【数位DP】【hdu 4352】XHXJ's LIS
- HDU 4352 XHXJ's LIS 数位dp
- HDU 4352 XHXJ's LIS(数位DP)
- hdu 4352 XHXJ's LIS(数位dp)
- HDU 4352 XHXJ's LIS【数位DP】
- hdu 4352 XHXJ's LIS (数位dp)
- HDU 4352 XHXJ's LIS(数位DP)
- HDU 4352 XHXJ's LIS(数位dp+搜索)★
- hdu 4352 XHXJ's LIS (数位+状态DP)
- hdu 4352 XHXJ's LIS(数位DP)
- HDU 4352 XHXJ's LIS(数位dp)
- hdu 4352 XHXJ's LIS(LIS+数位DP,5级)
- 数位dp+LIS+状态压缩-hdu-4352-XHXJ's LIS
- HDU 4352 XHXJ's LIS 数位dp+lis
- hdu 4352 XHXJ's LIS --- 数位dp 状态压缩
- [数位dp+状态压缩] hdu 4352 XHXJ's LIS
- hdu 4352 - XHXJ's LIS (数位dp)多校联合
- 给EditText左右两边设置图片与监听(drawableLeft/drawableRight)/弹出键盘
- MIT 线性代数(28—30)读书笔记
- opencv2、3舍弃了CvImage类,写好不容易找到
- DIG (类似nslookup)工具介绍
- java集合框架图和IO流知识图
- HDU 4352 XHXJ's LIS(数位dp)
- 第五次作业
- Easy Java
- 最大子串和
- 数据库的四种隔离级别
- eclipse常用技巧
- 读书笔记16 《傅雷家书》 傅雷傅敏
- string,stringbuilder,stringbuffer
- 波形发生器