[HDU]week6

课程

2602.Bone Collector

题目链接
背包问题,价值+体积

  • 贪心算法;
  • 动态规划;
  • 暴力搜索:
    • 0-1背包问题,对应唯一的二进制,设n=4,[0000,0001,0010,0011,…,1111]=2^4,对应唯一的十进制

eg1:

#include <iostream>
#include <bitset>//二进制
#include <cstdio>
using namespace std;

int main(){
    
    
    int i,j,n,v,T;
    int volume[1005],value[1005];
    scanf("%d",&T);
    while(T--){
    
    
        cin>>n>>v;
        for(i=0;i<n;i++)
        {
    
    
            scanf("%d",value+i);//数组名字时指针,&value[i]
        }
        for(i=0;i<n;i++)
        {
    
    
            scanf("%d",volume+i);
        }
        int max_value=-1;
        //8421码
        //1左移一位->10->2,时间复杂度:O(n)=2^n*n
        for(i=0;i<(1<<n);i++)//for(i=0;i<pow(2,n);i++)
        {
    
    
            //bitset<n> Bi(i);//将十进制整数i转成n位二进制
            bitset<32> Bi(i);
            int temp=i;
            int current_volume=0,current_value=0;
            for(j=0;j<n;j++)
            {
    
    
                if(Bi.test(j))//测试//if(temp%2==1)
                {
    
    
                    current_volume += volume[j];
                    current_value += value[j];
                }
                temp /= 2;
            }
            if(current_volume<=v && current_value>max_value)
            {
    
    
                max_value=current_value;
            }
        }
        cout<<max_value<<endl;
    }
    return 0;
}

eg2:

动态规划:空间换时间,类似归纳法

4549.M斐波那契数列

题目链接

#include <iostream>
#include <vector>
using namespace std;

int fib(int a, int b, int N) {
        if (N <= 1) return N;
        vector<int> dp(N + 1);
        dp[0] = a;
        dp[1] = b;
        for (int i = 2; i <= N; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[N];
}

int main(){
	int a,b,n;
	cin>>a>>b>>n;
	int res = fib(a,b,n);
	cout<<res<<endl;
	return 0;
}

练习

1231.最大连续子序列

#include <stdio.h>  // 动态规划
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct{
    
    
	int start,end;
	int weight;   //从i到k的最大子序列长度    状态迁移函数:t[i].weight=t[i+1].weight+arr[i]    i在序列中
}xulie;
xulie t[10005];
bool cmp(xulie a,xulie b)
{
    
    
	return a.weight>b.weight;
}
int main()
{
    
    
	int k,i,flag=0;
	int arr[10005];
//	freopen("f:/in.txt","r",stdin);
	while(~scanf("%d",&k)&&k)
	{
    
    
		for(i=1;i<=k;i++)
			cin>>arr[i];
 
		for(i=1;i<=k;i++)
		{
    
    
			t[i].weight=arr[i]>0?arr[i]:0;    //序列 从i到k的最大子序列长度初始化为 arr[i] 与 0 中的较大值
			t[i].start=t[i].end=i;
		}
 
		for(i=k-1;i>0;i--)    //逆推           critical codes
		{
    
    
			if(t[i+1].weight>0)
			{
    
    
				t[i].weight=t[i+1].weight+arr[i];
				t[i].start=i;
				t[i].end=t[i+1].end;
			}
		}
 
		sort(t+1,t+k,cmp);
 
		for(i=1;i<=k;i++)            //判断是否全是负值
		{
    
    
			if(arr[i]>=0)
				break;
		}
		if(i==k+1)     
			flag=1;
 
		if(flag)
			cout<<0<<" "<<arr[1]<<" "<<arr[k]<<endl;  //   全是负值情况输出
		else if(t[1].weight!=0)
			cout<<t[1].weight<<" "<<arr[t[1].start]<<" "<<arr[t[1].end]<<endl;
		else
			cout<<0<<" "<<0<<" "<<0<<endl;  //  若最大连续序列为0,直接输出0 0 0
		flag=0;
	}
//	fclose(stdin);
	return 1;
}

2955.Robberies

动态规划 - 0-1背包问题
被抓到的概率 - 抢到的钱数
背包 - 价值

dp[i][j]=从下标为0-i的物品里任意取,放入容量为j的背包,得到的最大价值

dp[i][j]=
1.不放物品i:=dp[i-1][j]
2.放物品i:=dp[i-1][j-weigtht[i]]+value[i]

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

dp[i][0]=0
dp[0][j]=
当 j < weight[0]时,dp[0][j] = 0,因为背包容量比编号0的物品重量还小。
当 j >= weight[0]时,dp[0][j] = value[0],因为背包容量放足够放编号0物品。

将银行总钱数作为背包容量。
不被抓情况下的最大钱数,即求最大的逃跑概率,所以是(1-p[i])。
从大到小遍历背包容量,概率超过(1-p)即输出。
状态方程:dp[j] = max(dp[j], dp[j - w[i]] * (1 - v[i])); //dp[i]为抢i金币后的总逃跑概率。
显然dp[0]=1;

#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <fstream>
#include <set>
using namespace std;
typedef long long ll;
#define MAXN 10005

double dp[MAXN];
double v[MAXN];
int w[MAXN];
int main() {
    
    
	int T;
	cin >> T;
    while (T--) {
    
    
        memset(dp, 0, sizeof(dp));
        double m;
        int n;
        cin >> m >> n;
        int sum = 0;
        for (int i = 1; i <= n; i++) {
    
    
            cin >> w[i] >> v[i];
            sum += w[i];
        }
        dp[0] = 1;
        for (int i = 1; i <= n; i++)
            for (int j = sum; j >= w[i]; j--)
                dp[j] = max(dp[j], dp[j - w[i]] * (1 - v[i]));

        for (int i = sum; i >= 0; i--) {
    
    
            if (dp[i] > (1 - m)) {
    
    
                cout << i << endl;
                break;
            }
        }
    }

	return 0;
}

1864.最大报销额

参考

可在系统通过,但是在codeblocks无法运行。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int v[100],w[100];
double dp[3000005];

int main()
{
    
    
    double q;
    int n,t;
    while(scanf("%lf%d",&q,&n)!=EOF)
    {
    
    
        double price;
        char ch;
        int j=0,k=0;
        if(n==0)
        {
    
    
            break;
        }

        for(int i=0; i<n; i++)
        {
    
    
            scanf("%d",&t);
            int flag=1;
            double a=0,b=0,c=0;
            while(t--)
            {
    
    
                getchar();
                scanf("%c:%lf",&ch,&price);
                if(ch=='A')//算出每个发票的类型A物品的总价格
                    a+=price;
                else if(ch=='B')//算出每个发票的类型B物品的总价格
                    b+=price;
                else if(ch=='C')//算出每个发票的类型C物品的总价格
                    c+=price;
                else//如果出现其他类型的物品就把flag标记为0,代表为不能报销的发票
                    flag=0;
                if(a>600||b>600||c>600)//如果A或者B或者C物品的单个价格有一个大于600就说明这个发票不能报销,就标记为0
                    flag=0;
            }
            if(flag==1&&(a+b+c)<=1000)//当flag等于1并且A,B,C的总钱数小于等于1000就是一张可以报销的发票
            {
    
    
                v[k]=(a+b+c)*100;//因为题目说了最后的结果是保留两位小数,我们就把所以数都转换为整形来使得计算更加简单,所以就乘以100.
                w[k]=(a+b+c)*100;//同上一样的作业
                k++;//存储完之后加1,接下来再存储满足条件可报销的情况
            }
        }
        int c=q*100;//这时候总钱数也需要乘以100.
        memset(dp,0,sizeof(dp));
        for(int i=0; i<k; i++)
        {
    
    
            for(int j=c; j>=w[i]; j--)
            {
    
    
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
        printf("%.2lf\n",dp[c]/100);
    }
}

自己:

#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <fstream>
#include <set>
using namespace std;
typedef long long ll;
#define MAXN 10005

int bag(vector<int> weight,vector<int> value,int bagWeight) {
    
    
    vector<vector<int>> dp(weight.size(), vector<int>(bagWeight + 1, 0));

    for (int j = weight[0]; j <= bagWeight; j++) {
    
    
        dp[0][j] = value[0];
    }

    for(int i = 1; i < weight.size(); i++) {
    
     // 遍历物品
        for(int j = 0; j <= bagWeight; j++) {
    
     // 遍历背包容量
            if (j < weight[i]) dp[i][j] = dp[i - 1][j];
            else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

        }
    }

    return dp[weight.size() - 1][bagWeight];
}

int main() {
    
    
    double w;
    int n,m;
    while(scanf("%lf %d", &w, &n)!=EOF){
    
    
        if(n==0)    break;
        double price;
        char type;
        int a,b,c;
        vector<int> weight,value;
        for(int i=0;i<n;i++){
    
    
            cin>>m;
            int flag=1;
            while(m--){
    
    
                scanf("%c:%lf",&type,&price);
                if(type=='A')   a+=price;
                else if(type=='B')  b+=price;
                else if(type=='c')  c+=price;
                else    flag=0;
            }
            if(flag==1&&a<=600&&b<=600&&c<=600&&(a+b+c)<=1000){
    
    
                int sum=(a+b+c)*100;//发票总价值
                value.push_back(sum);//v:价值,每张发票的报销价值
                weight.push_back(sum);//w:重量,每张发票的报销价值
            }
        }
        w = w*100;//报销总数
        int money = bag(weight,value,w);
        printf("%.2lf\n",(double)money/100);
    }
    return 0;
}
/*
200.00 3
2 A:23.50 B:100.00
1 C:650.00
3 A:59.99 A:120.00 X:10.00

123.50
*/

1466.计算直线的交点数

Presentation Error

参考

#include <stdio.h>
int main()
{
    
    
    int a[21][191] = {
    
    0};
    for (int i = 0; i < 21; i++){
    
    
        a[i][0] = 1;
    }
    for (int x = 2; x <= 20; x++){
    
    
        for (int n = 0; n <= x; n++){
    
    
            for (int j = 0; j <= (n - 1) * n / 2; j++){
    
    
                if (a[n][j] == 1)

                    a[x][(x - n) * n + j] = 1;
            }
        }
    }
    int n;
    while (scanf("%d", &n) != EOF){
    
    
    	for (int i = 0; i <= (n - 1) * n / 2; i++){
    
    
        	if (a[n][i] == 1){
    
    
            	printf("%d ", i);
        	}
    	}
    	printf("\n");
    }
    return 0;
}

accepted:

参考

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    
    
	int dp[21][192];
	int n,i,j,r;
	for(i=0;i<21;i++)//i条直线
	{
    
    
		for(j=0;j<192;j++)//j个交点
		{
    
    
			if(j==0) dp[i][j]=1;//与0条线平行
			else dp[i][j]=0;
		}
	}
	for(i=0;i<21;i++)
	{
    
    
		for(r=0;r<i;r++)
		{
    
    
			for(j=0;j<192;j++)
			{
    
    
				if(dp[r][j]==1)
					dp[i][(i-r)*r+j]=1;
			}
		}
	}
	while(~scanf("%d",&n))
	{
    
    
		for(i=0;i<n*(n-1)/2;i++)
		{
    
    
			if(dp[n][i])
			cout<<i<<" ";
 
		}
		cout<<i<<endl;
		
	}
	return 0;
}

2151.Worm

#include<stdio.h>
#include<string.h>
/*
 *dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1]:
 *表示第i分钟,第j棵树时的行走方案数;
 *初始化:dp[0][p]=1
 */
int dp[105][105];
int main()
{
    
    

    int n,m,p,t;
    int i,j;
    while(scanf("%d%d%d%d",&n,&p,&m,&t)!=EOF)
    {
    
    
        memset(dp,0,sizeof(dp));
        dp[0][p]=1;
        for(i=1;i<=m;i++)
        {
    
    
            for(j=1;j<=n;j++)
                     dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1];
        }
        printf("%d\n",dp[m][t]);
    }
    return 0;
}

2084. 数塔

#include<cstdio>
#include<string.h>
#include<algorithm>
#include<iostream>
/*
dp[i][j] = 加入第i行第j列,最大的和
dp[i][j] =max(dp[i-1][j],dp[i-1][j-1])+dp[i][j]
dp[0][j]=0
dp[i][0]=0
 */
using namespace std;

int main()
{
    
    
    int t,h,temp;
    scanf("%d",&t);
    while(t--){
    
    
        scanf("%d",&h);
        int dp[h+5][h+5];
        memset(dp,0,sizeof(dp));
        int num[h+5][h+5];
        memset(num,0,sizeof(num));
        int len=1;
        int temp_h=h;
        while(temp_h--){
    
    //5
            for(int i=1;i<=len;i++){
    
    
                    cin>>temp;
                    num[len][i]=temp;
            }
            len++;
        }
        for(int i=1;i<=h;i++){
    
    
            for(int j=1;j<=h;j++){
    
    
                dp[i][j] =max(dp[i-1][j],dp[i-1][j-1])+num[i][j];
            }
        }
        /*
        cout<<"num:\n"<<endl;
        for(int i=1;i<=h;i++){
            for(int j=1;j<=h;j++){
                printf("%d ",num[i][j]);
            }
            cout<<endl;
        }
        cout<<"dp:\n"<<endl;
        for(int i=1;i<=h;i++){
            for(int j=1;j<=h;j++){
                printf("%d ",dp[i][j]);
                if(dp[h][j]>maxnum){
                    maxnum=dp[h][j];
                }
            }
            cout<<endl;
        }*/
        int maxnum=0;
        for(int j=1;j<=h;j++){
    
    
            if(dp[h][j]>maxnum){
    
    
                maxnum=dp[h][j];
            }
        }
        cout<<maxnum<<endl;
    }

    return 0;
}

2059.龟兔赛跑

参考

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;
double dp[200];
#define INF 0xfffffff

int main()
{
    
    
	double l,c,t,v1,v2,vr,a[100000];
	int n;
	while(scanf("%lf%d%lf%lf%lf%lf%lf",&l,&n,&c,&t,&vr,&v1,&v2)!=EOF)
	{
    
    
		int i,j;
		double s;
		double time=0;
		for(i=1;i<=n;i++)
		{
    
    
			scanf("%lf",&a[i]);
		}
		a[0]=0;
		a[n+1]=l;
		dp[0]=0;
		for(i=1;i<=n+1;i++)
		{
    
    
			dp[i]=INF;
			for(j=0;j<i;j++)
			{
    
    
				s=a[i]-a[j];
				if(c>=s)
					time=(s*1.0)/v1;
				else
					time=((s-c)*1.0)/v2+(c*1.0)/v1;
				time+=dp[j];
				if(j>0)
					time+=t;
				dp[i]=min(dp[i],time);
			}
		}
		if(dp[n+1]>(l*1.0)/vr)
			printf("Good job,rabbit!\n");
		else
			printf("What a pity rabbit!\n");
	}
}

1069.Monkey and Banana

参考1参考2

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 35 * 3;
int d[N], n;
struct Cube
{
    
    
    int a, b, c;
    Cube (int aa = 0, int bb = 0, int cc = 0) : a (aa), b (bb), c (cc) {
    
    }
} cub[N];

int dp (int i)
{
    
    
    if (d[i] > 0) return d[i];
    d[i] = cub[i].c;
    for (int j = 1; j <= 3 * n; ++j)
        if ( (cub[i].a < cub[j].a && cub[i].b < cub[j].b) || (cub[i].a < cub[j].b && cub[i].b < cub[j].a))
            d[i] = max (d[i], dp (j) + cub[i].c);
    return d[i];
}

int main()
{
    
    
    int cas = 0, ans, a, b, c;
    while (scanf ("%d", &n), n)
    {
    
    
        memset (d, 0, sizeof (d));
        for (int i = ans = 0; i < n; ++i)
        {
    
    
            scanf ("%d%d%d", &a, &b, &c);
            cub[3 * i + 1] = Cube (a, b, c);
            cub[3 * i + 2] = Cube (a, c, b);
            cub[3 * i + 3] = Cube (b, c, a);
        }
        for (int i = 1; i <= 3 * n; ++i)
            ans = max (ans, dp (i));
        printf ("Case %d: maximum height = %d\n", ++cas, ans);
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
int dp[105];
struct node
{
    
    
    int l,w,h;    
}t[105];//存放箱子 
bool cmp(node a,node b)
{
    
    
    if(a.l!=b.l) return a.l>b.l;
    if(a.w!=b.w) return a.w>b.w;
}
int main()
{
    
    
    int n,m,k,g=0;;
    while(cin>>n,n)
    {
    
    
        int a,b,c;
        k=0;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
    
    
            cin>>a>>b>>c;
            t[++k].l=a;t[k].w=b;t[k].h=c;
            if(t[k].l<t[k].w) swap(t[k].l,t[k].w);
            t[++k].l=b;t[k].w=c;t[k].h=a;
            if(t[k].l<t[k].w) swap(t[k].l,t[k].w);
            t[++k].l=c;t[k].w=a;t[k].h=b;
            if(t[k].l<t[k].w) swap(t[k].l,t[k].w);
        }//箱子的高度有三种放法 
        t[0].l=1e9,t[0].w=1e9,t[0].h=0;
        sort(t+1,t+1+k,cmp);
        int maxx=0;
        for(int i=1;i<=k;i++)
        {
    
    
            for(int j=0;j<i;j++)
            {
    
    
                if(t[i].l<t[j].l&&t[i].w<t[j].w)
                {
    
    
                    dp[i]=max(dp[i],dp[j]+t[i].h);    
                    maxx=max(maxx,dp[i]); 
                }    
            }
        }//下降子序列 
        g++;
        printf("Case %d: maximum height = %d\n",g,maxx);
        
    }    
}
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct Node{
    
    
    int l;
    int w;
    int h;
    int s;
};

bool cmp(Node a,Node b)
{
    
    
    return a.s>b.s;
}

int main()
{
    
    
    int n,i,j,k,x,y,z,nu;
    Node in[99];
    int dp[500];
    nu=1;
    while(scanf("%d",&n)!=EOF && n!=0)
    {
    
    
        k=0;
        memset(dp,0,sizeof(dp));
        for(i=1;i<=n;i++)
        {
    
    
            scanf("%d %d %d",&x,&y,&z);
            k++;
            in[k].l=x ,in[k].w=y ,in[k].h=z ,in[k].s=x*y;
            k++;
            in[k].l=y ,in[k].w=z ,in[k].h=x ,in[k].s=y*z;
            k++;
            in[k].l=z ,in[k].w=x ,in[k].h=y ,in[k].s=x*z;
        }
        sort(in+1,in+k+1,cmp);
        dp[1]=in[1].h;
        for(i=2;i<=k;i++)
        {
    
    
            dp[i]=in[i].h;
            for(j=1;j<i;j++)
            {
    
    
                if((in[i].l<in[j].l && in[i].w<in[j].w)||(in[i].w<in[j].l && in[i].l<in[j].w))
                {
    
    
                    if(dp[j]+in[i].h>dp[i])
                        dp[i]=dp[j]+in[i].h;
                }
            }
        }
        int ma=0;
        for(i=1;i<=k;i++)
            if(dp[i]>ma)
                ma=dp[i];
        printf("Case %d: maximum height = %d\n",nu,ma);
        nu++;
    }
    return 0;
}

1058.Humble Numbers

参考

#include <stdio.h>
#define N 5843
int HN[5850],f2=1,f3=1,f5=1,f7=1;
int min(int a,int b,int c,int d)
{
    
    
return a>b?b>c?c>d?d:c:d>b?b:d:c<a?d<c?d:c:d<a?d:a;//求出最小值
}
void count(int HN[])
{
    
    
    int i;
    HN[1]=1;
    for(i=2; i<=N; i++)
    {
    
    
        HN[i]=min(HN[f2]*2,HN[f3]*3,HN[f5]*5,HN[f7]*7);//状态转移方程
        if(HN[i]==HN[f2]*2) f2++;
        if(HN[i]==HN[f3]*3) f3++;
        if(HN[i]==HN[f5]*5) f5++;
        if(HN[i]==HN[f7]*7) f7++;
    }
}
int main()
{
    
    
    int t;
    count(HN);
    while(~scanf("%d",&t)&&t!=0)
    {
    
    
        if(t%10==1&&t%100!=11)
            printf("The %dst humble number is %d.\n",t,HN[t]);
        else if(t%10==2&&t%100!=12)
            printf("The %dnd humble number is %d.\n",t,HN[t]);
        else if(t%10==3&&t%100!=13)
            printf("The %drd humble number is %d.\n",t,HN[t]);
        else
            printf("The %dth humble number is %d.\n",t,HN[t]);
    }
    return 0;
}

1159.Common Subsequence

题目前面介绍了一下子序列:一个字符串的子序列是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
题目问题是:找到 X 和 Y 的最大长度共同子序列的长度

#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

int longestCommonSubsequence(string text1, string text2) {
    
    
        vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1, 0));
        for (int i = 1; i <= text1.size(); i++) {
    
    
            for (int j = 1; j <= text2.size(); j++) {
    
    
                if (text1[i - 1] == text2[j - 1]) {
    
    
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
    
    
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[text1.size()][text2.size()];
}

int main()
{
    
    
    string s1,s2;
    while(cin>>s1>>s2){
    
    
        int num = longestCommonSubsequence(s1,s2);
        cout<<num<<endl;
    }
    return 0;
}

1087.Super Jumping! Jumping! Jumping!

题意:求上升序列的最大和/最长递增子序列

#define N 1010
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int k[N],dp[N],n;
int main()
{
    
    
    while(scanf("%d",&n)&&n)
    {
    
    
        memset(dp,0,sizeof(dp));
        for(int i=0; i<n; i++)
            scanf("%d",&k[i]);
        dp[0]=k[0];
        for(int i=1; i<n; i++)
        {
    
    
            for(int j=0; j<i; j++)
                if(k[i]>k[j])//k[i]>k[j]说明依第j项为队尾的上升序列和第i项可以构成上升序列
                    dp[i]=max(dp[i],dp[j]+k[i]);
            dp[i]=max(dp[i],k[i]);//这个是前j项可能存在负数的情况
        }
        int ma=-1;
        for(int i=0; i<n; i++)
            ma=max(ma,dp[i]);
        printf("%d\n",ma);
    }
    return 0;
}

1176.免费馅饼

思维参考:
动态规划、另类数塔;
2084-数塔:求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少
参考

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>

using namespace std;
const int N= 100008;
int f[N][12]; //position in a time then position in all time
int dp[N][12];

int main(){
    
    
	int n;
	while(~scanf("%d",&n)&&n){
    
    
		memset(f, 0, sizeof(f));
		memset(dp, 0, sizeof(dp));
		int x,T,maxT=0,m=0;
		while(n--){
    
    
			scanf("%d %d",&x,&T);
			f[T][x]++;
			maxT=max(maxT,T);
		}
		dp[1][4]=f[1][4];
		dp[1][5]=f[1][5];
		dp[1][6]=f[1][6];
		for(int i= 2;i<=maxT;i++){
    
    
			for(int j= 0;j<=10;j++){
    
    
				dp[i][j]=max({
    
    dp[i -1][j -1],dp[i -1][j],dp[i -1][j+ 1]})+f[i][j];
				m=max(m,dp[i][j]);
			}
		}
		printf( "%d\n",m);
	}
}

猜你喜欢

转载自blog.csdn.net/Jingle_dog/article/details/121099787