qduoj 140 题目6 142 ycb的ACM进阶之路

来源:互联网 发布:三公棋牌软件 编辑:程序博客网 时间:2024/05/29 19:12

题目6

发布时间: 2017年5月22日 14:30   最后更新: 2017年5月22日 14:33   时间限制: 1000ms   内存限制: 128M

6.png

给n,m,k,求上述方程中( X1 , X2 ... Xn , Y1 , Y2 ... Ym )解的个数(其中Xi>0,Yi>0) 


|:二进制按位或运算,1|0=1,0|0=0,1|1=1,0|1=1.

第一行输入三个正整数,n,m,k(n,m,k<=400)

输出一个数代表答案,答案可能会很大,所以结果对1000000007取模。

复制
1 1 1 
1
复制
1 2 3
8

暴力枚举左半部分和右半部分的值,就把问题转换成x1+x2+x3+..+xn=k1有多少种解,因为xi正数,可以想着把k1分成k1个1,在这k1个1里面插n-1个隔板,分成n个部分,隔板的放置方案数也就是解的个数,C(n-1,k1-1)。这样两边都这样求,最后乘一乘加一加。

数据小,求组合数的部分可以用杨辉三角预处理等等。。

#include<iostream>#define mod 1000000007using namespace std;long long c[1000][1000];int main(){         intn, m, k;         longlong ans = 0;         c[0][0]= 1;         for(inti = 1; i <= 500; i++){                   c[i][0]= 1;                   for(intj = 1; j <= i; j++){                            c[i][j]= (c[i - 1][j - 1] + c[i - 1][j]) % mod;                   }         }         cin>> n >> m >> k;         for(inti = 1; i <= k; i++){                   for(intj = 1; j <= k; j++){                            if((i| j) == k && i >= n && j >= m)ans = (ans + c[i - 1][n - 1] * c[j - 1][m - 1] % mod) % mod;                   }         }         cout<< ans << endl;}


ycb的ACM进阶之路

发布时间: 2017年5月22日 14:30   最后更新: 2017年5月22日 14:31   时间限制: 1000ms   内存限制: 128M

  ycb是个天资聪颖的孩子,他的梦想是成为世界上最伟大的ACMer。为此,他想拜附近最有威望的dalao为师。dalao为了判断他的资质,给他出了一个难题。dalao把他带到一个到处都是题的oj里对他说:“孩子,这个oj里有一些不同的题,做每一道题都需要一些时间,每一题也有它自身的rp(人品值)。我会给你一段时间,在这段时间里,你可以做一些题。如果你是一个聪明的孩子,你应该可以让做题的总rp最大。”   如果你是ycb,你能完成这个任务吗?

输入文件的第一行是一个T,表示测试组数,接下来T组每组第一行包含两个正整数N,M。M表示总共能够用来做题的时间,N代表oj里的题目的数目。接下来的N行每行包括两个的整数,分别表示做每个题的时间Ti和这道题的人品值Vi。
1 <= N, M <= 100000,
1 <= Ti, Vi <= 10

输出文件仅包含一个整数表示规定时间内可以做题得到的最大人品值。

复制
13 9 10 10 8 1 1 2
3
 多重背包

这个题第一眼看肯定会想到裸的01背包,但很明显时间不允许(当时只顾着考虑卡掉01背包的数据,忽略了贪心。。。。。。。。),从数据上看T和V的值都很小,所以可以从这个方面入手,根据不同的T和V都对应着种状态,统计这个状态的背包的数量,然后进行多重背包加一些优化(单调栈,二进制应该都可以)即可。

#include<bits/stdc++.h>using namespace std;int book[20][20];int dp[100005];int main(){    int T,i,j,ii,jj;    cin>>T;    while(T--)    {        int t,v;        memset(book,0,sizeof(book));        memset(dp,0,sizeof(dp));        int n,m;        cin>>n>>m;        for(i=0;i<n;i++)        {            scanf("%d %d",&t,&v);            book[t][v]++;        }        for(i=1;i<=10;i++)        {            for(j=1;j<=10;j++)            {                for(ii=1;ii<<1<book[i][j];ii<<=1)                {                    for(jj=m;jj>=ii*i;jj--)                    {                        dp[jj]=max(dp[jj],dp[jj-ii*i]+ii*j);                    }                }                ii=book[i][j]-ii+1;                for(jj=m;jj>=ii*i;jj--)                {                     dp[jj]=max(dp[jj],dp[jj-i*ii]+j*ii);                }            }        }        cout<<dp[m]<<endl;    }    return 0;}



原创粉丝点击