【DP】poj1037

来源:互联网 发布:js给div设置id 编辑:程序博客网 时间:2024/06/04 17:43

有点麻烦的一个DP

一开始已经想到只跟顺序有关系,但是忘记了只要维护一个上升一个下降就可以解决转移的问题了

然后还有一个点就是其实把任意一个数拿出去的话剩下序列跟拿出的数的关系是能推导出的。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>using namespace std;long long f[31][31][3];bool flag[31];int n,t;long long m;void dfs(int x,int y,long long w,int d){int tmp_tot=0;for (int i=1;i<=n;i++){if (flag[i]==true) tmp_tot++;if (tmp_tot==x) {printf("%d",i);flag[i]=false;break;}}if (w==0) return;long long tmp=0;if (d==0)for (int i=1;i<x;i++){tmp+=f[i][y][0];if (tmp>=w) {printf(" ");dfs(i,y-1,w-(tmp-f[i][y][0]),1);return;}}elsefor (int i=x;i<=y;i++){tmp+=f[i][y][1];if (tmp>=w){printf(" ");dfs(i,y-1,w-(tmp-f[i][y][1]),0);return;}}return;}int main(){freopen("test.in","r",stdin);freopen("test2.out","w",stdout);scanf("%d",&t);f[1][1][0]=1;f[1][1][1]=1;for (int i=2;i<=20;i++)for (int j=1;j<=i;j++){for (int k=1;k<j;k++)f[j][i][1]+=f[k][i-1][0];for (int k=j;k<i;k++)f[j][i][0]+=f[k][i-1][1];}while (t--){memset(flag,1,sizeof(flag));long long ans=0;scanf("%d%lld",&n,&m);for (int i=1;i<=n;i++){ans+=f[i][n][1];if (ans>=m) {dfs(i,n-1,m-(ans-f[i][n][1]),0);if (t) printf("\n");break;}ans+=f[i][n][0];if (ans>=m) {dfs(i,n-1,m-(ans-f[i][n][0]),1);if (t) printf("\n");break;}}}return 0;}

0 0
原创粉丝点击