• ACM Steps_Chapter Three_Section2


    Max Sum

    #include<iostream>
    using namespace std;
    int a[100001];
    int main()
    {
    	int T;
    	int i,n,position1,end,thissum,maxsum,begin;
    	cin>>T;
    	for(int tt=1;tt<=T;tt++)
    	{
    		cin>>n;
    		for(i=0;i<n;i++)
    			scanf("%d",&a[i]);
    		position1=begin=end=0;
    		maxsum=thissum=a[0];
    		for(i=1;i<n;i++)
    		{
    			if(thissum+a[i]<a[i])//如果当前值比a[i]小的话则改为a[i]  
    			{
    				thissum=a[i];
    				position1=i;	//记录下改的位置  
    			}
    			else
    			{
    				thissum=thissum+a[i];
    			}
    			if(thissum>maxsum)	//当前值比最大值大,则头尾都要改
    			{
    				maxsum=thissum;
    				begin=position1;
    				end=i;
    			}
    		}
    		printf("Case %d:\n%d %d %d\n",tt,maxsum,begin+1,end+1); 
    		if(tt!=T)
    		{
    			cout<<endl;
    		}
    	}
    	system("pause");
    	return 0;
    }
    

    Common Subsequence

    #include<iostream>
    #include<cstring>
    using namespace std;
    char str1[1001];
    char str2[1001];
    int dp[1001][1001];
    int main()
    {
    	int i,j,max,len1,len2;
    	while(cin>>str1>>str2)
    	{
    		len1=strlen(str1);
    		len2=strlen(str2);
    		for(i=0;i<len1;i++)
    		{
    			dp[i][0]=0;
    		}
    		for(i=0;i<len2;i++)
    		{
    			dp[0][i]=0;
    		}
    		for(i=1;i<=len1;i++)
    		{
    			for(j=1;j<=len2;j++)
    			{
    				if(str1[i-1]==str2[j-1])
    				{
    					dp[i][j]=dp[i-1][j-1]+1;
    				}
    				else
    				{
    					dp[i][j]=dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1];
    				}
    			}
    		}
    		cout<<dp[len1][len2]<<endl;
    	}
    	system("pause");
    	return 0;
    }
    	
    

    FatMouse's Speed

    /*
    首先按照关键字W升序进行排序,然后S[i]从1到i-1(是指外层循环中的第i个元素)开始遍历,
    找到w[i]>w[k],s[i]<s[k],使m[i]最大的位置,并记录。
    动态规划状态方程为:f[i] = max(f[k]+1,f[i]),1<=k<i;
    这里定义了一个struct mice 其中的len代表当前元素的状态长度,用来找到找到最长的,
    index用来记忆当前元素的真实下标,在排序后还能找到元素的下标。
    before用来找的当前元素的上一个元素的下标。
    */
    #include <iostream>
    #include <stdlib.h>
    using namespace std;
    typedef struct
    {
        int w,s;
        int len,index;
        int before;
    }mice;
    int cmp(const void *a,const void *b)
    {
        mice c = *(mice *)a;
        mice d = *(mice *)b;
        if(c.w==d.w)
        return d.s - c.s;
        else return c.w - d.w;
    }
    int main()
    {
        mice m[10001];
        int i = 1,flag,max=0,f[1001];
        while(cin>>m[i].w>>m[i].s)
        {
            m[i].index = i;
            m[i].len=0;
            m[i].before=0;
            i++;
        }
        //cout<<i<<endl;
        qsort(m,i-1,sizeof(m[1]),cmp);
        for(int j = 1;j < i ;j++)
        {
            for(int k = 1; k< j;k++)
            {
                if(m[j].w>m[k].w&&m[j].s<m[k].s)
                {
                    if(m[j].len<m[k].len+1)
                    {
                        m[j].len = m[k].len+1;
                        m[j].before = k;
                        if(m[j].len>=max)
                        {
                            max = m[j].len;
                            flag = j;
                        }
                    }
    
    
                }
            }
        }
        cout<<max+1<<endl;
        f[1] = m[flag].index;
        i=2;
         while(m[flag].before!=0)
        {
            flag = m[flag].before;
            f[i] = m[flag].index;
            i++;
        }
        for(int j = i-1 ; j >=1 ; j--)
        {
            cout<<f[j]<<endl;
        }
       // for(int j = 1 ; j < i ;j++)
       // cout<<m[j].index<<" "<<m[j].w<<" "<<m[j].s<<endl;
        return 0;
    }
    

    Humble Numbers

    /*
    分析:用dp的思维解答
    
     若一个数是Humble数,那么他的2、3、5、7倍仍然是Humble数。
    
     定义a为第i个Humble数
    
     a[n] = min( 2*a[m],3*a[n],5*a[k],7*a[l] ),m,n,k,l在被选择后彼此移动。
     */
    #include <iostream>
    using namespace std;
    int main()
    {
        int a[5843]={1},i,j,k,l,m,n,x[4],min;
        m = n = k = l = 1;
        for(i = 1;i < 5843;i++)
        {
              x[0]=a[m-1]*2;
              x[1]=a[n-1]*3;
              x[2]=a[k-1]*5;
              x[3]=a[l-1]*7;
              min = x[0];
              if (x[1] < min)
                 min = x[1];
              if (x[2] < min)
                 min = x[2];
              if (x[3] < min)
                 min = x[3];
              a[i] = min;
              if(min == x[0])
                 m++;
              if(min == x[1])
                 n++;
              if(min == x[2])
                 k++;
              if(min == x[3])
                 l++;
        }
        while(cin >> n,n)
        {
              if(n % 10 == 1 && n % 100 != 11)
                   printf("The %dst humble number is %d.\n",n,a[n-1]);
              else if(n % 10 == 2 && n % 100 != 12)
                   printf("The %dnd humble number is %d.\n",n,a[n-1]);
              else if(n % 10 == 3 && n % 100 != 13)
                   printf("The %drd humble number is %d.\n",n,a[n-1]);
              else
                   printf("The %dth humble number is %d.\n",n,a[n-1]);
        }
        return 0;
    }
    

    Monkey and Banana

    /*
    类似于最长上升子序列,把箱子拆成3*n个,这样相当于把一个箱子分成高度不同的3个,
    按底面积从小到大排好,根据转移方程dp[i]=max{dp[j]}+c[i](1<=j<i&&a[i]>a[j]&&b[i]>b[j]),
    其中dp[i]表示前i个箱子能堆起的最大高度。
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct R
    {
    	int a;
    	int b;
    	int c;
    	int s;
    }r[200];
    bool cmp(R a,R b)
    {
    	return a.s<b.s;
    }
    int main()
    {
    	int m=1,n,i,j,k,l,w,h,dp[200],temp,ans;
    	while(scanf("%d",&n)!=-1&&n)
    	{
    		ans=0;
    		memset(dp,0,sizeof(dp));
    		k=1;
    		for(i=1;i<=n;i++)
    		{
    			scanf("%d%d%d",&l,&w,&h);
    			r[k].a=l;r[k].b=w;r[k].c=h;r[k].s=r[k].a*r[k].b;
    			k++;
    			r[k].a=w;r[k].b=l;r[k].c=h;r[k].s=r[k].a*r[k].b;
    			k++;
    			r[k].a=h;r[k].b=l;r[k].c=w;r[k].s=r[k].a*r[k].b;
    			k++;
    			r[k].a=h;r[k].b=w;r[k].c=l;r[k].s=r[k].a*r[k].b;
    			k++;
    			r[k].a=l;r[k].b=h;r[k].c=w;r[k].s=r[k].a*r[k].b;
    			k++;
    			r[k].a=w;r[k].b=h;r[k].c=l;r[k].s=r[k].a*r[k].b;
    			k++;
    		}
    		sort(r+1,r+k,cmp);
    		dp[1]=r[1].c;
    		for(i=1;i<k;i++)
    		{
    			temp=0;
    			for(j=1;j<i;j++)
    				if(r[i].a>r[j].a&&r[i].b>r[j].b&&temp<dp[j])
    					temp=dp[j];
    			dp[i]=temp+r[i].c;
    		}
    		for(i=1;i<k;i++)
    			if(ans<dp[i])
    				ans=dp[i];
    		printf("Case %d: maximum height = %d\n",m++,ans);
    	}
    	return 0;
    }
    

    数塔

    /*
    此题采用动态规划自底向上计算,如果我们要知道所走之和最大,
    那么最后一步肯定是走最后一排数其中一个,向上退,
    倒数第二步肯定走最后一排数对应的倒数第二排最大的一个
    (将最后对应最后步走的最大的数加起来存在倒数第二步的数组中)再向上推,
    一直推到最上面的第0布,那么b[0][0]最后所存的结果一定是最大的
    */
    
    #include<iostream>
    using namespace std;
    int main()
    {
    	int T;
    	int a[101][101];
    	int dp[101][101];
    	cin>>T;
    	while(T--)
    	{
    		int n;
    		cin>>n;
    		for(int i=0;i<n;i++)
    		{
    			for(int j=0;j<=i;j++)
    			{
    				cin>>a[i][j];
    			}
    		}
    		dp[0][0]=0;
    		for(int i=n-1;i>=0;i--)
    		{
    			for(int j=i;j>=0;j--)
    			{
    				if(i==n-1)
    				{
    					dp[i][j]=a[i][j];
    				}
    				else
    				{
    					dp[i][j]=max(a[i][j]+dp[i+1][j],a[i][j]+dp[i+1][j+1]);
    				}
    			}
    		}
    		cout<<dp[0][0]<<endl;
    	}
    	system("pause");
    	return 0;
    }
    

    免费馅饼

    #include<stdio.h>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int dp[100005][12];
    int main()
    {
        int n,i,j,maxt;
        int x,t;
        while(scanf("%d",&n),n)
        {
            maxt=0;
            memset(dp,0,sizeof(dp));
            for(i=0;i<n;i++)
            {
                scanf("%d%d",&x,&t);
                dp[t][x]++;
                if(maxt<t)  
    				maxt=t;
            }
            for(i=maxt-1;i>=0;i--)
            {
                dp[i][0]+=max(dp[i+1][1],dp[i+1][0]);
                for(j=1;j<11;j++)
                {
                    dp[i][j]+=max(max(dp[i+1][j-1],dp[i+1][j]),dp[i+1][j+1]);
                }   
            }
            printf("%d\n",dp[0][5]);     
        }
        return 0;  
    }
    

    命运

    /*
    设f[i][j]为走到(i,j)位置得到的最大权值。
    则f[i][j] = max {f[i-1][j],f[i][j-1],f[i][j*k](2<k <m/j)}+a[i][j]。
    再把f[i][j]初始化成-inf.f[1][1] =a[0][0].
    */
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    
    int main()
    {
        int c,n,m,a[21][1010],dp[21][1010],max;
        cin>>c;
        while(c--)
        {
            cin>>n>>m;
            memset(dp,0,sizeof(dp));
           // max = -101
            for(int i = 1 ; i <= n ; i++)
            {
                for(int j = 1 ; j <= m ; j++)
                {
                   // cin>>a[i][j];
                   scanf("%d",&a[i][j]);
                    dp[i][j] = a[i][j];
                    if(i == 1) 
    					max = -101;//注意:有出现全负,所以第一行应设为小于最小值。
                    else 
    					max = dp[i-1][j];
                    for(int k = 1 ; k <= j/2;k++)
                    {
                        if(j%k==0)
                        	if(max<dp[i][k])
                        		max = dp[i][k];
                    }
                    if(max < dp[i][j-1])
                    	max = dp[i][j-1];
                    dp[i][j] += max;
                }
            }
            cout<<dp[n][m]<<endl;
        }
        return 0;
    }
    


  • 相关阅读:
    学习ReentrantLock
    新博客地址:WWW.BG7YWL.COM
    LimeSDR 无线信号重放攻击和逆向分析
    LimeSDR 上手指南
    GSM:嗅探语音流量
    制作一个老旧C118的GSM便携式测试设备
    SMS PDU编码数据串格式分析
    闪付卡(QuickPass)隐私泄露原理
    低成本制作基于OpenWRT的渗透工具
    Inside a low budget consumer hardware espionage implant
  • 原文地址:https://www.cnblogs.com/oldoldb/p/3311321.html
Copyright © 2020-2023  润新知