TYVJ1076

数字三角形2
从三角形顶端走到最下面一行所经过数字的和sum mod 100要最大
一开始,我就想确定最后的值是最大的关键的地方在哪里,想老久也想不出,觉得这不可能的事情嘛,后来看了题解,原来这是类似于存在性验证的一类DP,即求出0...99哪个结果可能出现,然后取其中的最大值就是结果。
设状态vis[i][j][k]表示到(i,j)的时候能否达到k值,如果可以就==true。从下到上扫过去,对于每个(i,j)只可能从下一行的左边或右边上来,所以只需要遍历一遍下一行左边和右边所能得到的值k,然后vis[i][j][(k+a[i][j])%100] = true,这样到vis[1][1][]后,从0到99扫一遍vis[1][1][i]就能得到最大值
存在性的DP确实很强大很有用啊

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 26;
 7 bool vis[maxn][maxn][100];
 8 int a[maxn][maxn];
 9 int main()
10 {
11     int n;
12     cin>>n;
13     for(int i = 1;i<=n;++i)
14         for(int j = 1;j<=i;++j)
15             scanf("%d",&a[i][j]);
16     memset(vis,false,sizeof(vis));
17     for(int i = 1;i<=n+1;i++)
18         vis[n+1][i][0] = true;
19     for(int i = n;i>0;--i)
20         for(int j = 1;j<=i;++j)
21             for(int k = 0;k<100;++k)
22             {
23                 if(vis[i+1][j][k])vis[i][j][(k+a[i][j])%100] = true;
24                 if(vis[i+1][j+1][k])vis[i][j][(k+a[i][j])%100] = true;
25             }
26     for(int i = 99;i>=0;--i)
27         if(vis[1][1][i]){printf("%d\n",i);break;}
28
29
30     return 0;
31 }
时间: 2024-10-17 18:00:53

TYVJ1076的相关文章