hdu 4055 Number String【2011 ACM Asia Dalian Regional Problem E】
另类作法:dp[i][j]表示第i位前面没有用过的数字比他小的有j个,对于某个i,j的一种状态第i+1位的选择都能唯一的到达另外一种状态,最后输出dp[len][0]即可,另外还有合法串的变换进行DP . 另外n^3需要化为n^2 .
View Code
1 ///自己的做法
2 inline void gao()
3 {
4 int i,j;
5 int len=strlen(s);
6 int idx;
7 n=len+1;
8 memset(dp,0,sizeof(dp));
9 memset(sum,0,sizeof(sum));
10 int temp=0;
11 for(i=0;i<=n-1;i++)
12 {
13 dp[0][i]=1;
14 temp+=1;
15 sum[0][i]=temp;
16 }
17 for(i=1,idx=0;i<=len;idx++,i++)
18 {
19 int temp=0;
20 for(j=0;j<=n-1;j++)
21 {
22 //if(i+j>=n) break;
23 ///这里不能搞掉 因为这里还有个sum[j]要处理 要搞出sum[n-1]~~
24 if(s[idx]=='D')
25 {
26 dp[i][j]=sum[i-1][n-1]-sum[i-1][j];
27 if(dp[i][j]<0) dp[i][j]+=mood;
28 }
29 else
30 if(s[idx]=='I')
31 {
32 if(j<=n-i-1)
33 dp[i][j]=sum[i-1][j];
34 }
35 else
36 {
37 dp[i][j]=sum[i-1][n-1]-sum[i-1][j];
38 if(dp[i][j]<0) dp[i][j]+=mood;
39 if(j<=n-i-1)
40 dp[i][j]+=sum[i-1][j];
41 if(dp[i][j]>=mood) dp[i][j]-=mood;
42 }
43 temp+=dp[i][j];
44 if(temp>=mood) temp-=mood;
45 sum[i][j]=temp;
46 }
47 }
48 printf("%d\n",dp[len][0]);
49 }
50 ///网上流传作法:
51 这题最需要理解的一个性质是当加入一个新的数n时,如果想把n放在前n-1个位置的任何一个,
52
53 并且不影响升降性质,只需要在之前方案中把当前在n位置的数x(n放前面必然有一个x要放在n的位置)
54
55 所有的大于等于x的数都加1即可。比如之前方案是(1,5,3,2,4),现在把3放在第6位。
56
57 则对应方案是(1,6,4,2,5,3)。(1,2不变,其他加一)
posted on 2011-10-15 11:20 yaoz10051538 阅读(493) 评论(0) 编辑 收藏 举报