$CF41D\ Pawn$

\(problem\)

这题 灰常的相似
然后内存可能过大 开个滚动数组
因为数塔问题总是 只需要上面一行的两个状态(这题就是数塔问题)
下面的代码与原题不符。(原题要输出路径)想抄的可以走了
输出路径只需要数组记录一下就好了。

#ifdef Dubug

#endif
#include <bits/stdc++.h>
using namespace std;
typedef long long LL ;
inline LL In() {
    LL res(0),f(1);
    register char c ;
    while(isspace(c=getchar())) ;
    c == '-'? f = -1 , c = getchar() : 0 ;
    while(res = (res << 1) + (res << 3) + (c & 15) , isdigit(c=getchar())) ;
    return res * f ;
}
int n , m , k ;
const int N = 900 + 5 ;
const int Arr = 100 + 5 ;
short num[Arr][Arr] ;
bool dp[Arr][Arr][N] ;
bool b[N] ;
char s[Arr] ;
inline void get(int x) {
    for(register int i=1; i<=N/x; i++) b[i*x] = true ;
    return ;
}
inline void Ot() {
    memset(dp,0,sizeof(dp)) ;
    for(register int j=1; j<=m; j++) dp[n][j][num[n][j]] = true ;
    for(register int i=n-1; i>=1; i--)
        for(register int j=1; j<=m; j++)
            for(register int q=0; q<N; q++) {
                if(dp[(i+1)][j-1][q]) dp[i][j][q+num[i][j]] = true ;
                if(dp[(i+1)][j+1][q]) dp[i][j][q+num[i][j]] = true ;
            }
    int Max = -1 ;
    for(register int i=1; i<=m; i++)
        for(register int q=0; q<N; q++) if(dp[1][i][q] and b[q]) Max = max (Max,q) ;
    cout << Max << endl ;
}
signed main() {
#ifdef Online_Judge
    freopen("test.in","r",stdin) ;
    freopen("testdata.out","w",stdout) ;
#endif
    n = In() , m = In() , k = In() ;
    for(register int i=1; i<=n; i++) {
        scanf("%s",s+1);
        for(register int j=1; j<=m; j++) num[i][j] = s[j]&15 ;
    }
    get(k+1) ;
    return Ot() , 0 ;
}
#ifdef Dubug

#endif
#include <bits/stdc++.h>
using namespace std;
typedef long long LL ;
inline LL In() {
    LL res(0),f(1);
    register char c ;
    while(isspace(c=getchar())) ;
    c == '-'? f = -1 , c = getchar() : 0 ;
    while(res = (res << 1) + (res << 3) + (c & 15) , isdigit(c=getchar())) ;
    return res * f ;
}
int n , m , k ;
const int N = 900 + 5 ;
const int Arr = 100 + 5 ;
short num[Arr][Arr] ;
bool dp[2][Arr][N] ;
bool b[N] ;
char s[Arr] ;
inline void get(int x) {
    memset(b,false,sizeof(b)) ;
    for(register int i=1; i<=N/x; i++) b[i*x] = true ;
    return ;
}
inline void Ot() {
    memset(dp,0,sizeof(dp)) ;
    for(register int j=1; j<=m; j++) dp[n&1][j][num[n][j]] = true ;
    for(register int i=n-1; i>=1; i--)
        for(register int j=1; j<=m; j++)
            for(register int q=0; q<N; q++) {
                if(dp[(i+1)&1][j-1][q]) dp[i&1][j][q+num[i][j]] = true ;
                if(dp[(i+1)&1][j+1][q]) dp[i&1][j][q+num[i][j]] = true ;
            }
    int Max = -1 ;
    for(register int j=1; j<=m; j++)
        for(register int q=0; q<N; q++) if(dp[1][j][q] and b[q]) Max = max (Max,q) ;
    cout << Max << endl ;
}
signed main() {
#ifdef Online_Judge
    freopen("test.in","r",stdin) ;
    freopen("testdata.out","w",stdout) ;
#endif
    n = In() , m = In() , k = In() ;
    for(register int i=1; i<=n; i++) {
        scanf("%s",s+1);
        for(register int j=1; j<=m; j++) num[i][j] = s[j]&15 ;
    }
    get(k+1) ;
    return Ot() , 0 ;
}

转载于:https://www.cnblogs.com/qf-breeze/p/10630924.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值