• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
JackSlowFuck
博客园    首页    新随笔    联系   管理    订阅  订阅

20140708总结

今天的题还是比较水的。。涨自信?

第一题。。显而易见的dp:dp[i][j][k][l][m]:表示i位,j个1,k是否顶上界,l个前导零,是否仍在前导零上。转移方程比较复杂,详见代码。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 long long dp[50][50][2][50][2];
 6 long long work(long long x)
 7 {
 8     long long top[200];
 9     memset(dp,0,sizeof(dp));
10     memset(top,0,sizeof(top));
11     long long i=1;
12     long long j=1;
13     if(x==0) return 0;
14     while(x/j)
15     {
16         i++;
17         j*=2;
18     }
19     if(i)
20         i--;
21     long long n=i;
22     while(x)
23     {
24         top[i]=x%2;
25         x/=2;
26         i--;
27     }
28 //    for(int i=1;i<=n;i++)
29 //        cout<<top[i];
30 //    cout<<endl<<endl;
31     dp[1][0][1][0][0]=1;
32 //    for(int i=1;i<=n;i++)
33 //        cout<<top[i];
34 //    cout<<endl;
35     for(i=1;i<=n;i++)
36         for(j=0;j<=n/2;j++)
37             for(int k=0;k<=n;k++)
38             {
39                 dp[i+1][j][0][k+1][0]+=dp[i][j][0][k][0];
40                 dp[i+1][j+1][0][k][1]+=dp[i][j][0][k][0];
41                 if(top[i]==0)
42                     dp[i+1][j][1][k+1][0]+=dp[i][j][1][k][0];
43                 else
44                 {
45                     dp[i+1][j][0][k+1][0]+=dp[i][j][1][k][0];
46                     dp[i+1][j+1][1][k][1]+=dp[i][j][1][k][0];
47                 }
48                 for(long long l=0;l<=1;l++)
49                     dp[i+1][j+l][0][k][1]+=dp[i][j][0][k][1];
50                 for(long long l=0;l<=top[i];l++)
51                     dp[i+1][j+l][l==top[i]][k][1]+=dp[i][j][1][k][1];
52 //                cout<<dp[i][j][up]<<endl;
53             }
54     long long ans=0;
55     for(int k=0;k<=n;k++)
56         for(int i=1;i<=(n-k)/2;i++)
57         {
58             ans+=dp[n+1][i][0][k][1]+dp[n+1][i][1][k][1];
59         }
60     
61 //    for(int j=1;j<=n+1;j++)
62 //    for(int k=0;k<=n;k++)
63 //    for(int i=1;i<=n;i++)
64 //        cout<<dp[j][i][0][k][1];
65     return ans;
66 }
67 void work()
68 {
69     freopen("testA.in","r",stdin);
70     freopen("testA.out","w",stdout);
71     long long L,R;
72     cin>>L>>R;
73     if(L==1)
74         cout<<work(R)<<endl;
75     else
76         cout<<work(R)-work(L-1)<<endl;
77 //    cout<<work(R)<<"  "<<work(L-1)<<endl;
78 }
79 int main()
80 {
81     work();
82     return 0;
83 }
View Code

 第二题比较复杂,大意就是把[ai,bi] 作为区间,落在[1,N]上,互不重叠,长度互不相等。然后dp[j][k]表示在i位,选了k个,其和为j。

然后答案就是,详见标程代码(我还没有写出来)。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 using namespace std;
 6 const long long MOD =1000000007LL;
 7 long long dp[1007][1007];
 8 long long C[2014][2014];
 9 long long x[101];
10 #ifdef unix
11 #define LL "%lld\n"
12 #else 
13 #define LL "I64d\n"
14 #endif
15 void init()
16 {
17     memset(dp,0,sizeof(dp));
18     memset(C,0,sizeof(C));
19     memset(x,0,sizeof(x));
20     x[0]=1;
21     for(int i=1;i<=100;i++)
22         x[i]=x[i-1]*i%MOD;
23     for(int i=1;i<1000;i++)
24     {
25         C[i][i]=1;
26         C[i][0]=1;
27         for(int j=1;j<i;j++)
28         {
29             C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
30         }
31     }
32     dp[0][0]=1;
33     for(int i=1;i<=1000;i++)    
34         for(int j=1000;j>=i;j--)
35             for(int k=50;k>0;k--)
36                 dp[k][j]=(dp[k][j]+dp[k-1][j-i])%MOD;
37 }
38 int main()
39 {
40     init();
41     int T,N,K;
42     cin>>T;
43     long long ans=0;
44     while(T--)
45     {
46         cin>>N>>K;
47         if(K*(K+1)/2>N)
48         {
49             printf("0\n");
50             continue;
51         }
52         ans=0;
53         for(int L=K;L<=N;L++)
54         {
55             ans=(ans+dp[K][L]*C[N+K-L][K]%MOD)%MOD;
56         }
57         printf("%lld\n",(ans*x[K])%MOD);
58     }
59 }
View Code

 

第三题比较水,我就不多说什么了,多特判就好了。。

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int main()
 5 {
 6     freopen("testC.in","r",stdin);
 7     freopen("testC.out","w",stdout);
 8     int n,m,x;
 9     cin>>n>>m>>x;
10     if(x<0)
11     {
12         cout<<0<<endl;
13         return 0;
14     }
15     if(x==0)
16     {
17         cout<<n*m/2<<endl;
18         return 0;
19     }
20     x-=1;
21     n-=2*x;
22     m-=2*x;
23     if(n<=0||m<=0)
24         cout<<0<<endl;
25     else if(n==1||m==1)
26         cout<<n*m-n*m/2<<endl;
27     else
28         cout<<(n+m)-2<<endl;
29     return 0;
30 }
View Code

 

 

posted @ 2014-07-08 17:32  JackSlowFuck  阅读(218)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3