北邮新生排位赛2解题报告a-c

来源:互联网 发布:移动教学软件 编辑:程序博客网 时间:2024/06/05 07:07


时间限制 1000 ms 内存限制 65536 KB

题目描述

丁神要去Google上班了,去之前丁神想再做一道水题,但时间不多了,所以他希望题目做起来既水又快。现在一共有n道题,编号从1到n,每道题有两个值aba为做这道题需要的时间,b为题目的“水值”,丁神希望做b/a最大的那题。

输入格式

输入第一行为数据组数T(T10),接下来T组数据,每组数据中第一行为一个数nn为题目的数量,接下来n行,每行两个正整数ab。如果两道题b/a的值是一样的就输出a比较小的,如果还一样就输出编号比较靠前的。 1a,b109,1n100000)

输出格式

对于每组数据,输出对应的题目编号,每个输出占一行。

输入样例

123 54 8

输出样例

2
水题不解释,数据颇大,不能排序,卡在cin,5次

#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <cmath>#include <vector>using namespace std;const double eps=10e-7;int main(){ios::sync_with_stdio(false);    int t;    cin>>t;    while(t--){        int n;        cin>>n;        double maxd=0;        int a,b;        int mina;        int ans;        for(int ni=1;ni<=n;ni++){            cin>>a>>b;            if(maxd<b/a){                maxd=b/a;                mina=a;                ans=ni;            }            else if(fabs(maxd-b/a)<eps){                if(a<mina){                    mina=a;                    ans=ni;                }            }        }        cout<<ans<<endl;    }    return 0;}




时间限制 1000 ms 内存限制 65536 KB

题目描述

丁神又要去Google上班了,这一次丁神想多做几道水题,并使题目的总水量最大.丁神同一时刻只能在水一道题,只有做完这道题才能得到它的水值,丁神的总时间为t,现在一共有n道题,编号从1到n,每道题有两个值aba为做这道题需要的时间,b为题目的水值。

输入格式

输入第一行为数据组数T(T10),接下来T组数据,每组数据中第一行为两个数tnn为题目的数量,t为总时间,接下来n行,每行两个正整数ab(1a,t10001n1001b1000000000)

输出格式

对于每组数据,输出对应的最大总水量,每个输出占一行。

输入样例

110 28 166 12

输出样例

16
咳咳..其实我第一次的时候交的贪心我会说吗?看来dp还是意识缺乏,简单的01背包


#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <cmath>#include <vector>using namespace std; class query{    public:    int a,b,index;};bool cmp(query q1,query q2){        long long  i=(q1.b*q2.a)-(q2.b*q1.a);        if(i>0)return true;        if(i<0)return false;        if(q1.a>q2.a)return true;        if(q1.a<q2.a)return false;        if(q1.index<q2.index)return true;        return false;}query que[120];long long dp[120][1200];int main(){    int t;    ios::sync_with_stdio(false);    cin>>t;    //cout<<t<<endl;    while(t--){        int n,time;        cin>>time>>n;        int a,b;        for(int ni=0;ni<n;ni++){            cin>>a>>b;            que[ni].a=a;            que[ni].b=b;            que[ni].index=ni;        }       // for(int ni=0;ni<n;ni++){         //   cout<<que[ni].a<<" "<<que[ni].b<<" "<<que[ni].index<<endl;        //}        sort(que,que+n,cmp);        long long ans=0;       // for(int ni=0;ni<n;ni++){       //     cout<<que[ni].a<<" "<<que[ni].b<<" "<<que[ni].index<<endl;       // }       memset(dp,0,sizeof(dp));       dp[0][que[0].a]=que[0].b;       for(int i=0;i<n;i++){           for(int j=1;j<=time;j++){               dp[i][j]=max(dp[i][j],dp[i][j-1]);               if(i)dp[i][j]=max(dp[i][j],dp[i-1][j]);               if(i&&j>=que[i].a){                   dp[i][j]=max(dp[i][j],dp[i-1][j-que[i].a]+que[i].b);                }            //cout<<"dp"<<i<<" "<<j<<" "<<dp[i][j]<<endl;            }        }        cout<<dp[n-1][time]<<endl;    }    return 0;}



c:

时间限制 1000 ms 内存限制 65536 KB

题目描述

现有一段横向长度为N的山脉,其中每段有一个独一无二的高度Hi(1到N之间的正整数)。现在你想知道对于长度为N的山脉,可能有这样的山脉多少种。这样的山脉是:某个位置要么比两边的高度都低,要么比两边的高度都高。两座山脉 A和 B 不同当且仅当存在一个 i,使得 Ai≠Bi。由于这个数目可能很大,你只对它除以 P 的余数感兴趣。

输入格式

输入以EOF为结束,每组仅含一行,两个正整数 N, P。 3≤N≤4200,P≤10^9

输出格式

对于每组数据输出仅含一行,一个非负整数,表示你所求的答案对 P 取余之后的结果。

输入样例

4 7

输出样例

3说明:共有 10 种可能的山脉,它们是:1324    1423    2143    2314    24133142    3241    3412    4132    4231 
又是dp

又没找出关系

...........

总之就是好好思考...

对k+1选取k+1作为基点,它在哪段都会成为最大点,上顶点,

设左边长度j:

左边 ans[j]

右边 ans[k-j]

ans(k+1)=SUM(c[j][k]*ans[j]*ans[k-j])

ym吴大神,刘大神

接下来注意不要爆运算中的int就行了(改成longlong)

#include <iostream>using namespace std;#define MAXN 4202int c[MAXN][MAXN];long long ans[MAXN];int main(){    int n,p;    while(cin>>n>>p){        c[1][1]=c[1][0]=1;        for(int i=2;i<=n;i++){            c[i][0]=1;            for(int j=1;j<=i;j++){                c[i][j]=(c[i-1][j-1]+c[i-1][j])%p;            }        }        ans[0]=1%p;        ans[1]=1%p;        ans[2]=1%p;        ans[3]=2%p;        for(int i=4;i<=n;i++){            for(int j=0;j<i;j+=2){                ans[i]=ans[i]%p+((c[i-1][j])*(ans[i-1-j])%p*ans[j])%p;                ans[i]%=p;            }        }        cout<<ans[n]*2%p<<endl;    }}


0 0
原创粉丝点击