zoukankan      html  css  js  c++  java
  • 寒假5

    [蓝桥杯][2013年第四届真题]剪格子

    如下图所示,3  x  3  的格子中填写了一些整数。 
    +--*--+--+ 
    |10*  1|52| 
    +--****--+ 
    |20|30*  1| 
    *******--+ 
    |  1|  2|  3| 
    +--+--+--+  
    我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。 
    本题的要求就是请你编程判定:对给定的m  x  n  的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。 
    如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。  
    如果无法分割,则输出  0。 

    输入
    程序先读入两个整数  m  n  用空格分割  (m,n< 10)。 
    表示表格的宽度和高度。 
    接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。 
    输出
    输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。 
    样例输入
    3  3 
    10  1  52 
    20  30  1 
    1  2  3  
    样例输出
    3
    dfs 4个参数,前面两个代表坐标,第三个代表不断变化的总和,最后一个是总和相等的个数,取较小者。
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <stdlib.h>
    #include <queue>
    using namespace std;
    const int inf=0x3f3f3f;
    int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    int maps[15][15];
    int vis[15][15];
    int n,m,all=0,ans=inf;
    void dfs(int x,int y,int sum,int cnt)
    {
       if(sum>all/2)
        return ;
       if(sum==all/2)
        ans=min(ans,cnt);
       else
       {
           for(int i=0;i<4;i++)
           {
               int xx=x+dir[i][0];
               int yy=y+dir[i][1];
               if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy])
               {
                   vis[xx][yy]=1;
                   dfs(xx,yy,sum+maps[xx][yy],cnt+1);
                   vis[xx][yy]=0;
               }
           }
       }
    }
    int main()
    {
        scanf("%d%d",&m,&n);
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                scanf("%d",&maps[i][j]);
                all+=maps[i][j];
            }
        }
        memset(vis,0,sizeof(vis));
        vis[0][0]=1;
        dfs(0,0,maps[0][0],1);
        if(ans==inf)
        {
            cout<<0<<endl;
        }
        else
        {
            cout<<ans<<endl;
        }
        return 0;
    }

    问题描述
      给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。

      其中,A的子矩阵指在A中行和列均连续的一块。
    输入格式
      输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
      接下来n行,每行m个整数,表示矩阵A。
    输出格式
      输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。
    样例输入
    3 3
    -1 -4 3
    3 4 -1
    -5 -2 8
    样例输出
    10
    题目大意:求连续行、列的子矩阵的最大元素和。由于行、列必须是连续的,所以可以先求出每一列前n行的和,然后再枚举一个 行的开始和结束就可以啦,然后再用最大字段和求出最大和。本质是将二维的转化为一维的。

    #include <iostream>
    #include<bits/stdc++.h>
    using namespace std;
    long long dp[505][505];
    int main()
    {
        long long n,m,i,j,k;
        cin>>n>>m;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                cin>>dp[i][j];
                dp[i][j]+=dp[i][j-1];
            }
        }
        long long maxx=dp[1][1];
        for(i=1;i<=m;i++)
        {
            for(j=i;j<=m;j++)
            {
                long long s=0;
                for(k=1;k<=n;k++)
                {
                    s+=dp[k][j]-dp[k][i-1];
                    if(s>maxx)
                        maxx=s;
                    if(s<0)
                        s=0;
                }
            }
        }
        cout<<maxx<<endl;
        return 0;
    
    }
    一个正整数可以划分为多个正整数的和,比如n=3时: 
    3;1+2;1+1+1; 
    共有三种划分方法。 
    给出一个正整数,问有多少种划分方法。 

    数据规模和约定 
    n< =100 

    输入
    一个正整数n 
    输出
    一个正整数,表示划分方案数 
    样例输入
    3 
    样例输出
    3
    动态规划题

    建立一个二维数组横行代表将一个数拆几份

          竖行代表要拆分的数那么方案数=arr[n][k].

          我们要简化状态对于每一种分法我把它分成两种情况

          1.分法里至少有一个1  比如 5 = 1+2+2  5 = 1+1+3

          2.分法里没有1  比如 5 = 3+2 

          所以方案数=没有1的所有分法+有1的所有分法

    #include <iostream>
    #include<bits/stdc++.h>
    using namespace std;
    int vis[101][101];
    int f(int m,int i)
    {
        if(vis[m][i])
            return vis[m][i];
        if(m==i||i==1)
            return 1;
        if(i>m)
            return 0;
        return vis[m][i]=f(m-1,i-1)+f(m-i,i);
    }
    int main()
    {
     int n;
     cin>>n;
     long long  sum=0;
     for(int i=1;i<=n;i++)
     {
         sum+=f(n,i);
     }
     cout<<sum<<endl;
     return 0;
    }
    题目描述
    小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆。通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号。为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。 
    试编程计算,一共有多少种不同的摆花方案。 

    样例说明

    有2种摆花的方案,分别是(1,1,1,2),  (1,1,2,2)。括号里的1和2表示两种花,比如第一个方案是前三个位置摆第一种花,第四个位置摆第二种花。 
    数据规模和约定 
    对于100%数据,有0< n≤100,0< m≤100,0≤  ai≤100。 

    输入
    第一行包含两个正整数n和m,中间用一个空格隔开。 
    第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1、a2、……an。 
    输出
    输出只有一行,一个整数,表示有多少种方案。注意:因为方案数可能很多,请输出方案数对1000007取模的结果。
    样例输入
    2  4 
    3  2 
    样例输出
    2
    #include <iostream>
    #include<bits/stdc++.h>
    using namespace std;
    #define mod 1000007
    int a[505][105],f[105];
    int main()
    {
      int n,m;
      cin>>n>>m;
      int i,j;
      for(i=1;i<=n;i++)
      {
          cin>>f[i];
      }
      a[0][0]=1;
      for(i=1;i<=n;i++)
      {
          for(j=0;j<=m;j++)//摆放的总盆数
          {
              for(int h=0;h<=min(j,f[i]);h++)//第i种花摆放k盆
              {
                  a[i][j]=(a[i][j]+a[i-1][j-h])%mod;
              }
          }
      }
      cout<<a[n][m]<<endl;
      return 0;
    }
  • 相关阅读:
    Sublime安装package control的操作
    Sublime的简单操作
    C# 泛型方法
    C# 数组的讲解(ArrayList 与List的区别)
    免费的天气API
    bootstrapValidator的验证
    sqlServer 多行合并为一行
    bootstrap的安装注意
    SQL数据库中把一个表中的数据复制到另一个表中
    JavaScript的误区
  • 原文地址:https://www.cnblogs.com/kepa/p/10453237.html
Copyright © 2011-2022 走看看