zoukankan      html  css  js  c++  java
  • 模板1

    最优子矩阵

     1 /*对于一个矩阵而言,如果我们将连续k行的元素纵向相加,并对相加后所得的数列求连续最大和,则此连
     2 
     3 续最大和就是一个行数为k的最优子矩阵!
     4 */
     5 
     6 #include<iostream>
     7 using namespace std;
     8 int rec[101][101];
     9 //int m=0;
    10 //void get(int ans[101],int nums)
    11 //{
    12 //    int b = 0;
    13 //    for(int i=0;i<nums;i++)
    14 //    {
    15 //        if(b<0)
    16 //            b = ans[i];
    17 //        else
    18 //            b +=ans[i];
    19 //        if(b>m)
    20 //            m = b;
    21 //    }
    22 //}
    23 int main()
    24 {
    25     int nums;
    26     int result[101];
    27     cin>>nums;
    28     int m=0;
    29     for(int i=0;i<nums;i++)
    30     {
    31         for(int j=0;j<nums;j++)
    32         {
    33             cin>>rec[i][j];
    34         }
    35     }
    36     for(int i=0;i<nums;i++)
    37     {
    38         memset(result,0,sizeof(result));
    39         for(int j=i;j<nums;j++)
    40         {            
    41             int b = 0;
    42             for(int k=0;k<=nums;k++)
    43             {
    44                 result[k]+=rec[j][k];
    45                 if(b<=0)
    46                     b = result[k];
    47                 else
    48                     b +=result[k];
    49                 if(b>m)
    50                     m=b;
    51             }
    52 
    53         }
    54     }
    55     cout<<m<<endl;
    56     return 0;
    57 }
    View Code

    括号匹配

     1 /*
     2 括号匹配问题
     3 前i个中 ) 的个数为 j个。
     4 初始化,dp[1][0]=1;
     5 
     6 设立 j 为 ) 比 ( 更加简单
     7 
     8 */
     9 
    10 #include<stdio.h>
    11 int dp[20][20];
    12 
    13 int main()
    14 {
    15     int i,j,n;
    16     while(scanf("%d",&n)>0)
    17     {
    18         if(n%2==1)
    19         {
    20             printf("0
    ");
    21             continue;
    22         }
    23         dp[1][0]=1;
    24         for(i=2;i<=n;i++)
    25         {
    26             for(j=0;j<=i/2;j++)
    27             {
    28                 dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
    29             }
    30         }
    31         printf("%d
    ",dp[n][n/2]);
    32     }
    33     return 0;
    34 }
    View Code

    RMQ

     1 /*
     2 
     3 RMQ 求解区间最值问题。
     4 
     5   满足动态规范方程:
     6   dp[i][j]=min{ dp[i][j-1],dp[i+( 1<<(j-1) )][j-1]  }
     7   利用的是二分的思想,表示dp[i][j],位置i开始,长度为j的最值
     8   分解成,dp[i][j-1] ,dp[i+( 1<<(j-1) )][j-1]
     9 
    10 */
    11 
    12 #include<iostream>
    13 #include<cstdlib>
    14 #include<cstring>
    15 #define N 1000
    16 using namespace std;
    17 
    18 int dp[N][N];
    19 int A[N];
    20 
    21 int hmin(int x,int y)
    22 {
    23     return x>y? x:y;
    24 }
    25 
    26 int RMQ(int L,int R) //查询的操作
    27 {
    28     int k=0;
    29     while(  (1<<(k+1))<=R-L+1 )k++;
    30     return hmin(dp[L][k-1],dp[L+(1<<(k-1))][k-1]);
    31 }
    32 
    33 void make_ini(int n)
    34 {
    35     int i,j,L,R,M;
    36     for(i=1;i<=n;i++)  //初始化
    37         dp[0][i]=A[i];
    38 
    39     for(j=1;(1<<j)<=n;j++) //元素编号从 1 到 n
    40         for(i=1;i+j-1<=n;i++)
    41             dp[i][j]=hmin(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    42 
    43 /*
    44     P198    
    45         
    46 */
    47     scanf("%d",&M);
    48     while(M--)
    49     {
    50         scanf("%d%d",&L,&R);
    51         printf("%d
    ",RMQ(L,R));
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     int n,i;
    58     while(scanf("%d",&n)>0)
    59     {
    60         for(i=1;i<=n;i++)
    61             scanf("%d",&A[i]);
    62         make_ini(n);
    63     }
    64     return 0;
    65 }
    View Code

    求二进制数中1的个数

     1 #include<stdio.h>
     2 int get(int i)
     3 {
     4     int count=0;
     5     while(i)
     6     {
     7         ++count;
     8         i=(i-1)&i;
     9     }
    10     return count;
    11 }
    12 int main()
    13 {
    14     int i;
    15     while(scanf("%d",&i)>0)
    16     {
    17         printf("%d
    ",get(i));
    18     }
    19 }
    View Code

    线段切割

     1 /*
     2 看了中学生的论文,
     3 学 线段切割
     4 
     5 
     6 线段
     7 a. ___________________.b
     8   
     9     c.___________.d
    10      
    11 */
    12 
    13 struct Line
    14 {
    15     int a;    //线段起始点
    16     int b;    //线段终点
    17     int longint; //长度
    18 };
    19 
    20 bool Function(int a,int b,int c,int d) 
    21 {
    22     if(a>=d || c>=b) return false;
    23     else return true;
    24 }
    25 //判断线段是否重叠。当满足a>=d || c>=b的时候,不满足.
    26 
    27 
    28 
    29 void Cut(int Num,int c,int d)
    30 {
    31     if(Line[Num].a<c) Add(Line[Num].a,c);
    32     if(d<Line[Num].b) Add(d,Line[Num].b);
    33     Delete(Num);
    34 }
    35 //切割线段过程。如最上方所示。
    36 
    37 /*
    38 线段
    39 a. ___________________.b
    40   
    41     c.___________.d
    42 */
    43 
    44 
    45 void Add(int a,int b)
    46 {
    47     total++;
    48     Line[total].a=a;
    49     Line[total].b=b;
    50 }
    51 //将一条线段增加到线段集合中
    52 
    53 
    54 void Delete(int Num)
    55 {
    56     Line[Num]=Line[total];
    57     total--;
    58 }
    59 //线段的删除过程,可以将集合中最后一天线段
    60 //移到要删除线段的位置
    View Code

    石子合并

     1 /*
     2 f(n3)超时,超空间。
     3 */
     4 
     5 #include<stdio.h>
     6 #include<stdlib.h>
     7 int dp[10005][10005];
     8 int sum[10005]={0};
     9 int a[10005];
    10 int mmin(int x,int y)
    11 {
    12     if(x<y)
    13         return x;
    14     else return y;
    15 }
    16 int main()
    17 {
    18     int n,i,j,k,len;
    19     while(scanf("%d",&n)>0)
    20     {
    21         if(n==0)break;
    22         for(i=1;i<=n;i++)
    23         {
    24             scanf("%d",&a[i]);
    25             sum[i]=sum[i-1]+a[i];
    26         }
    27         for(len=2;len<=n;len++)//长度
    28         {
    29             for(i=1;i<=n-len+1;i++) //起点
    30             {
    31                 j=i+len-1; //终点
    32                 dp[i][j]=0x7fff;
    33                 for(k=1;k<j;k++)
    34                     dp[i][j]=mmin(dp[i][j],dp[i][k]+dp[k+1][j]-sum[i-1]+sum[j]);
    35             }
    36         }
    37         printf("%d
    ",dp[1][n]);
    38     }
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    猴面包树果 baobab tree
    关于 韩国 申明 豆浆 和 端午 是其国家创造或历史的 看法
    初中英语课本里隐藏着的惊人秘密(转载)
    如果不出意外,我每周都会去工大打球
    新开始做wpf,随便写点经验
    当你老了 叶芝
    继承Form中的DevExpress控件不能打开编辑器Designer
    骑 自行车 从公司 到家
    LJP Little John PalmOS 1.0 Release 最新版 (RC9后的正式版)
    我的语文备忘
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3313194.html
Copyright © 2011-2022 走看看