bzoj5248(洛谷4363)(2018九省联考)一双木棋

洛谷P4363题目解析
本文针对洛谷P4363题目提供了一种解决方案,通过使用记忆化搜索算法并结合hash和map来优化搜索过程。该方法虽然能在bzoj平台上通过测试,但在洛谷平台可能会出现超时的情况,更高效的解决方法可能是采用轮廓线DP等技术。

题目:https://www.luogu.org/problemnew/show/P4363

一种考虑状态数的方法:有几个用了k个格子的列,就在第k个0的左边插入几个1;

  这也是求不降序列的个数的方法。本题中这样一看,一共有C(10,20)个状态。*m得出记忆化搜索的时间复杂度是18e6左右。

利用hash和map记忆化搜索。那个dg可以设成全局变量,每次复原一下,就不用专门解hash了。之所以还要记s是为了记忆化搜索作角标。

其实这个代码只能在bzoj上A,洛谷上会超时。不超时的方法似乎是轮廓线dp之类。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#define ll long long
using namespace std;
const ll INF=2e8;
int n,m,tot,base,dg[15];
ll a[2][15][15];
map<ll,ll> dp;
map<ll,bool> vis;
ll pw(ll a,int ct)
{
    ll ret=1;
    while(ct)
    {
        if(ct&1)ret*=a;
        a*=a;ct>>=1;
    }
    return ret;
}
ll dfs(ll s,bool k)
{
    if(vis[s])return dp[s];
    vis[s]=1;ll ret=-INF;
//    ll ts=s;
//    int dg[15]={0};
//    for(int i=1;i<=m;i++)dg[i]=ts%base,ts/=base;
    if(dg[m]==n)return 0;
    for(int i=1;i<=m;i++)
        if((i==1&&dg[i]<n)||dg[i-1]>dg[i])
        {
            dg[i]++;
            ret=max(ret,a[k][dg[i]][i]-dfs(s+pw(base,i-1),!k));
            dg[i]--;
        }
    return dp[s]=ret;
}
int main()
{
    scanf("%d%d",&n,&m);base=n+1;
    for(int k=0;k<=1;k++)for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%lld",&a[k][i][j]);
    printf("%lld",dfs(0,0));
    return 0;
}

 

转载于:https://www.cnblogs.com/Narh/p/9164002.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值