码迷,mamicode.com
首页 > 其他好文 > 详细

【提高组】

时间:2019-10-05 16:50:02      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:取数游戏   比较   code   避免   ems   opened   游戏   size   方程式   

P1005 矩阵取数游戏

区间DP。

可以看出每行互不影响,所以每次区间DP求出本行最大值,ans即加上每一行最大值。

转移方程式:f[L][R]=max(num[L]*p[k]+dp(L+1,R),dp(L,R-1)+num[R]*p[k])

技术图片
#include<bits/stdc++.h>
#define For(i,l,r) for(int i=l;i<=r;i++)
#define lll __int128
#define ll long long
using namespace std;
const int M=81;
int n,m,num[M];
lll ans,p[M],f[M][M];
inline ll read(){
    ll f=1,sum=0;
    char ch=getchar();
    while(!isdigit(ch)){if(ch==-)f=-1;ch=getchar();}
    while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
    return f*sum;
}
inline void write(lll x){
    if(x<0) putchar(-),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+0);
}
inline lll dp(int l,int r){
    if(f[l][r]!=-1) return f[l][r];
    if(r-l>=1) f[l][r]=max(num[l]*p[m-r+l]+dp(l+1,r),dp(l,r-1)+num[r]*p[m-r+l]);
    else f[l][r]=num[l]*p[m-r+l];
    return f[l][r];
} 
int main(){
    n=read(),m=read();
    p[0]=1;
    For(i,1,m) p[i]=p[i-1]*2;
    For(i,1,n){
        For(j,1,m) num[j]=read();
        memset(f,-1,sizeof(f));
        ans+=dp(1,m);
    } 
    write(ans);
    return 0;
}
View Code

 

P1373 小a和uim之大逃离

#蒟蒻看再久都不知从何下手,神犇一眼秒说是基础递推#

一个比较有趣的dp方程,f[i][j][p][k]中(i,j)表示所处位置,p代表魔夜差值,k代表最后一步是小a还是小uim走。a[i][j]即所处位置魔液值。ans加上f[i][j][0][1]。

转移方程式很好想+k是避免减出负数)

f[i][j][p][0]+=f[i-1][j][(p-a[i][j]+k)%k][1]

f[i][j][p][0]+=f[i][j-1][(p-a[i][j]+k)%k][1]

f[i][j][p][1]+=f[i-1][j][(p+a[i][j])%k][0]

f[i][j][p][1]+=f[i][j-1][(p+a[i][j])%k][0]

四维数组注意算空间内存。两次30分因为写成+=,别缩写啦!!

 

【提高组】

标签:取数游戏   比较   code   避免   ems   opened   游戏   size   方程式   

原文地址:https://www.cnblogs.com/jian-song/p/11624867.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!