ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

新学期学习总结5

2021-11-07 16:30:34  阅读:163  来源: 互联网

标签:总结 buy int scanf 学习 dp sc include 新学期


这一周继续做题,发现了自己很多的问题和不足需要改进。
P1064 [NOIP2006 提高组] 金明的预算方案
这是一道的背包题目,不过在原来完全背包的基础上增加了一些变化:每一件物品都有至多2个附件,只有加入该物品其附件才能加入。
刚开始有点糊涂,直接把附件当做一个物品,每次加入背包都判断一下,然后就直接超时。
后来看题解一想,其实可以每次判断主件是否需要加入背包时同时再判断加入0或者1或者2个附件是否会更好,这样既不会影响求背包又加快了速度。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct piece
{
    int x,y;
} buy[70][3];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int a,b,c;
    for(int j=1; j<=m; j++)
    {
        scanf("%d%d%d",&a,&b,&c);
        if(c==0)
        {
            buy[j][0].x=a;
            buy[j][0].y=b;
        }
        else if(buy[c][1].y==0)
        {
            buy[c][1].x=a;
            buy[c][1].y=b;
        }
        else
        {
            buy[c][2].x=a;
            buy[c][2].y=b;
        }
    }
    int dp[40000]= {0};
    for(int j=1; j<=m; j++)
        for(int i=n; i>=buy[j][0].x; i--)
        {
            dp[i]=max(dp[i],dp[i-buy[j][0].x]+buy[j][0].x*buy[j][0].y);
            if(i-buy[j][0].x-buy[j][1].x>=0)
                dp[i]=max(dp[i],dp[i-buy[j][0].x-buy[j][1].x]+buy[j][0].x*buy[j][0].y+buy[j][1].x*buy[j][1].y);
            if(i-buy[j][0].x-buy[j][2].x>=0)
                dp[i]=max(dp[i],dp[i-buy[j][0].x-buy[j][2].x]+buy[j][0].x*buy[j][0].y+buy[j][2].x*buy[j][2].y);
            if(i-buy[j][0].x-buy[j][1].x-buy[j][2].x>=0)
                dp[i]=max(dp[i],dp[i-buy[j][0].x-buy[j][1].x-buy[j][2].x]+buy[j][0].x*buy[j][0].y+buy[j][1].x*buy[j][1].y+buy[j][2].x*buy[j][2].y);
        }
    printf("%d\n",dp[n]);
}

不过这里主件的序号不是每个主件在所有主件中的顺序,而是每个主件在所有件中的顺序,就因为这个,找了好久,第二天才搞清楚。
P1065 [NOIP2006 提高组] 作业调度方案
这是一道模拟题,由于不了解这种题,刚开始我还以为是一道贪心题,后来又以为是一道dp,最后看了看题解才知道还有这种类型的题,然后仔细读了读题目才豁然开朗。

#include <iostream>
#include <cstdio>
#include <map>
using namespace std;

int main()
{
    int m,n;
    scanf("%d%d",&m,&n);
    int sx[401]={0},jqh[401]={0},sj[401]={0},x;
    map<int,int>c;
    for(int j=1;j<=n*m;j++)
    {
        scanf("%d",&x);
        c[x]++;
        sx[j]=(x-1)*m+c[x];
    }
    for(int j=1;j<=n*m;j++)
        scanf("%d",&jqh[j]);
    for(int j=1;j<=n*m;j++)
        scanf("%d",&sj[j]);
    int jq[21][8001]={0},fin[21]={0};
    for(int j=1;j<=n*m;j++)
    {
        int gj=sx[j]/m;
        int g=jqh[sx[j]];
        int time=sj[sx[j]];
        if(sx[j]%m)
            gj++;
        for(int i=fin[gj]+1;;i++)
        {
            if(jq[g][i]==0)
            {
                int pd=1;
                for(int t=i;t<=i+time-1;t++)
                    if(jq[g][t]!=0)
                        pd=0;
                if(pd==1)
                {
                    for(int t=i;t<=i+time-1;t++)
                        jq[g][t]=1;
                    fin[gj]=i+time-1;
                    break;
                }
            }
        }
    }
    int ans=0;
    for(int j=1;j<=n;j++)
        if(ans<fin[j])
            ans=fin[j];
    printf("%d\n",ans);
}

P1069 [NOIP2009 普及组] 细胞分裂
这是一道数学问题。给出一个底数和它的幂,然后要求从给出的数中找出经过最小的幂运算可以被其整除的数。这道题比较简单,只需要算出其中给出的底数的质因数在每个数中的个数然后判断一下就可以了。不过要注意时间复杂度的优化,不然会超时。
刚开始我直接把每一个数的质因数算了一遍,结果直接超时。

#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <climits>
using namespace std;
int pdss(int x)
{
    for(int j=2; j<=sqrt(x); j++)
        if(x%j==0)
            return 0;
    return 1;
}
int main()
{
    int n,m1,m2,s[10001]= {0};
    map<int,int>pd;
    scanf("%d%d%d",&n,&m1,&m2);
    for(int j=1; j<=n; j++)
        scanf("%d",&s[j]);
    s[0]=m1;
    if(m1==1)
    {
        printf("%d\n",0);
        return 0;
    }
    for(int i=2; pdss(m1)!=1&&i<=sqrt(m1); i++)
        while(m1%i==0)
        {
            pd[i]++;
            m1/=i;
        }
    if(m1!=1)
        pd[m1]++;
    for(map<int,int>:: iterator it= pd.begin(); it!=pd.end(); it++)
            it->second*=m2;
    int haveans=0,sc[10001]={0};
    for(int j=1; j<=n; j++)
    {
        int p=1;
        for(map<int,int>:: iterator it= pd.begin(); it!=pd.end(); it++)
            if(s[j]%it->first==0)
            {
                int js=0;
                while(s[j]%it->first==0)
                {
                    s[j]/=it->first;
                    js++;
                }
                int x=it->second/js;
                if(it->second%js!=0)
                    x++;
                sc[j]=max(x,sc[j]);
            }
            else
            {
                p=0;
                break;
            }
        if(p==1)
            haveans=1;
        else
            sc[j]=INT_MAX;
    }
    if(haveans==0)
        printf("%d\n",-1);
    else
    {
        sort(sc+1,sc+1+n);
        printf("%d\n",sc[1]);
    }
    return 0;
}

P1072 [NOIP2009 提高组] Hankson 的趣味题
这道题我刚开始直接暴力查找,然后超时。后来知道可以先找出b1的各个因数,然后再在其中判断即可,减少了很多的多余运算。

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define ll long long
int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    int n;
    ll a,b,c,d;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
        int ans=0;
        for(ll j=1; j<=sqrt(d); j++)
        {
            if(d%j!=0)
                continue;
            if(j%b==0&&gcd(j,a)==b&&j*c/gcd(j,c)==d)
                ans++;
            if(d/j==j)
                continue;
            if(d/j%b==0&&gcd(d/j,a)==b&&d/j*c/gcd(d/j,c)==d)
                ans++;
        }
        printf("%d\n",ans);
    }
}

通过做这几道题,发现找bug和优化计算的能力需要提高,而且现在做题太慢,需要不断提高。

标签:总结,buy,int,scanf,学习,dp,sc,include,新学期
来源: https://blog.csdn.net/qq_51844949/article/details/121192449

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有