数字三角形W( codevs 上的):
要求走到最后和mod 100 最大。
在mod 100 这个条件下,刚刚的状态就没有了最优子结构。
不能用简单的数字三角形求法来做,这很显然。
所以我们可以加一维来完成这个问题。
定义f (i,j,k)表示走到(i,j)位置时,能否达到(i,j)使其%100=k
状态转移方程就是f(i,j,k)=f(i+1,j,(k-a(i,j)+100)%100) | f(i+1,j,(k-a(i,j)+100)%100)
最后找f(1,1,i) 的能达到的i最大值即可。
代码如下。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<algorithm>
#include<cstdlib>
#define LL long long
#define reg register int
#define f(i,a,n) for(reg i=a;i<=n;i++)
using namespace std;
int n;
const int N=30;
int a[N][N],dp[N][N][100];
int main() {
cin>>n;
f(i,1,n)f(j,1,i){
scanf("%d",&a[i][j]);a[i][j]%=100;
}
for(int i=1;i<=n;i++)dp[n][i][a[n][i]]=1;
for(int i=n-1; i>=1; i--) {
for(int j=1; j<=i; j++) {
for(int k=0;k<=99;k++)
dp[i][j][k]=(dp[i+1][j][(k-a[i][j]+100)%100]||dp[i+1][j+1][(k-a[i][j]+100)%100]);
}
}
for(int i=99;i>=0;i--){
if(dp[1][1][i]){
cout<<i<<endl;return 0;
}
}
return 0;
}