数字三角形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;
}