数字三角形系列(Tyvj 1044 && 1076 && 1079 && 1084)

数字三角形1:

#include <stdio.h>
#include <string.h>
 
int a[30][30];
int dp[30][30];
 
int main (void)
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        memset(dp, 0,sizeof(dp));
        int i, j, k = 1;
        for(i = 0; i < n; i ++)
        {
            for(j = 0; j < k; j++)
            {
                scanf("%d", &a[i][j]);
            }
            k++;
        }
        k = 1;
        for(i = 0; i < n; i++)
            dp[n][i] = a[n][i];
        for(i = n - 1; i >= 0; i--)
        {
            for(j = 0; j < n; j++)
            {
                dp[i][j] = dp[i][j] + dp[i + 1][j] > dp[i + 1][j + 1] ? dp[i + 1][j] : dp[i + 1][j + 1];
                dp[i][j] += a[i][j];
            }
        }
        printf("%d\n", dp[0][0]);
    }
     
    return 0;
}


数字三角形2:

我刚开始还是按照数字三角形1的方法做的,果断WA。

因为有了mod100的限制,这一层最大的数,在下一层加上一个数mod100以后不一定还是最大的,所以应该枚举所以的情况。

枚举的方法是设置三维数组,dp[x][y][z]是1的话代表有一条路径走到map[x][y]这一点的数总和mod100的得数是z的这种情况存在,是0就代表不存在。

#include <stdio.h>

int a[50][50];
int dp[50][50][100];

int main (void)
{
	int n;
	while(scanf("%d", &n) != EOF)
	{
		int i, j, k;
		for(i = 1; i <= n; i++)
		{
			for(j = 1; j <= i; j++)
			{
				scanf("%d", &a[i][j]);
				a[i][j] %= 100;
			}
		}
		
		for(i = 1; i <= n; i++)
			dp[n][i][a[n][i]] = 1;
		
		for(i = n - 1; i > 0; i--)
		{
			for(j = 1; j <= i; j++)
			{
				for(k = 0; k < 100; k++)
				{
					if(dp[i + 1][j][k])
						dp[i][j][(k + a[i][j]) % 100] = 1;
					if(dp[i + 1][j + 1][k])
						dp[i][j][(k + a[i][j]) % 100] = 1;
				}
			}
		}
		for(i = 99; i >= 0; i--)
		{
			if(dp[1][1][i])
			{//找到最大值
				printf("%d\n", i);
				break;
			}
		}
	}
	return 0;
}


数字三角形3:

题目规定一定要经过n / 2,n / 2这一点,因为n / 2,n / 2 这一点是在三角形的斜边上,所以可以看出来,在1到n / 2 - 1行取的数一定都是斜边上的数。

那么在n / 2到n行用数字三角形1的方法处理,然后加上1到n / 2 - 1行斜边上的数,就是最后结果。

#include <stdio.h>
#include <string.h>

int a[50][50];
int dp[50][50];

int max(int x, int y)
{
	return x > y ? x : y;
}

int main (void)
{
	int n;
	while(scanf("%d", &n) != EOF)
	{
		memset(dp, 0, sizeof(dp));
		int i, j, k;
		for(i = 1; i <= n; i++)
		{
			for(j = 1; j <= i; j++)
				scanf("%d", &a[i][j]);
		}
		
		for(i = 1; i <= n; i++)
			dp[n][i] = a[n][i];
		
		int x = n / 2;
		for(i = n - 1; i >= x; i --)
		{
			for(j = 1; j <= i; j++)
			{
				dp[i][j] = max(dp[i + 1][j] , dp[i + 1][j + 1]);
				dp[i][j] += a[i][j];
				//printf("%d\n", dp[i][j]);
			}
		}
		dp[x - 1][x - 1] = dp[x][x] + a[x - 1][x - 1];
		for(i = x - 1; i > 0; i--)
		{
			dp[i][i] = dp[i + 1][i + 1] + a[i][i];
		}
		printf("%d\n", dp[1][1]);
		
	}
	return 0;
}

数字三角形4:

和数字三角形3不同的是,题目输入指定的点,让所走的路程一定经过这个点。

刚开始,我是想以所给的点位界限,分别向上和向下求最大值,然后相加,但是不好实现……要考虑的东西不少……写半天没实现……

偷偷看了下讨论区,有一种方法是把指定的位置的数加上一个比较大的数,然后用数字三角形1的方法做,这样路线就一定会经过所指定的那一点,最后将所得到的最大的值再减去那个比较大的数就是结果。感觉这种方法好机智……

#include <stdio.h>
#define NUM 10000000
int a[50][50];
int dp[50][50];

int main (void)
{
	int n, i, j;
	while(scanf("%d", &n) != EOF)
	{
		for(i = 1; i <= n; i++)
		{
			for(j = 1; j <= i; j++)
				scanf("%d", &a[i][j]);
		}		
		int x, y;
		scanf("%d %d", &x, &y);
		a[x][y] += NUM;
		
		for(i = 1; i <= n; i++)
			dp[n][i] = a[n][i];
		for(i = n - 1; i >= 1; i --)
		{
			for(j = 1; j <= i; j ++)
			{
				dp[i][j] = dp[i + 1][j] > dp[i + 1][j + 1] ? dp[i + 1][j] : dp[i + 1][j + 1];
				dp[i][j] += a[i][j];
			}
		}
		printf("%d\n", dp[1][1] - NUM);		
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值