NOI 97 (Vijos 1464)积木游戏(DP)

很普通的DP,设dp[i][j][k]为第i块积木放在第j堆且摆放状态为k的最高高度。方程很容易推出。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-8
# define MOD 1000000007
# define INF 1000000000
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<1,l,mid
# define rch p<<1|1,mid+1,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
    int res=0, flag=0;
    char ch;
    if((ch=getchar())=='-') flag=1;
    else if(ch>='0'&&ch<='9') res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')  res=res*10+(ch-'0');
    return flag?-res:res;
}
void Out(int a) {
    if(a<0) {putchar('-'); a=-a;}
    if(a>=10) Out(a/10);
    putchar(a%10+'0');
}
const int N=105;
//Code begin...

int a[N][3], dp[N][N][3];

bool check(int i, int b, int j, int c)
{
    int a1, a2, b1, b2;
    if (b==0) a1=1, a2=2;
    else if (b==1) a1=0, a2=2;
    else a1=0, a2=1;
    if (c==0) b1=1, b2=2;
    else if (c==1) b1=0, b2=2;
    else b1=0, b2=1;
    return (a[i][a1]<=a[j][b1]&&a[i][a2]<=a[j][b2])||(a[i][a2]<=a[j][b1]&&a[i][a1]<=a[j][b2]);
}
int main ()
{
    int n, m;
    scanf("%d%d",&n,&m);
    FOR(i,1,n) scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);
    FOR(i,1,n) FOR(j,1,i) {
        int ma=0;
        FO(k,0,i) FO(l,0,3) ma=max(ma,dp[k][j-1][l]);
        FO(l,0,3) dp[i][j][l]=ma+a[i][l];
        FO(k,j,i) FO(l1,0,3) FO(l2,0,3) if (check(i,l1,k,l2)) dp[i][j][l1]=max(dp[i][j][l1],dp[k][j][l2]+a[i][l1]);
    }
    int ans=0;
    FOR(i,m,n) FO(j,0,3) ans=max(ans,dp[i][m][j]);
    printf("%d\n",ans);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/lishiyao/p/6526621.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值