首页 > 其他 > 详细

BZOJ4715: 囚人的旋律 dp

时间:2020-06-02 12:34:12      阅读:33      评论:0      收藏:0      [点我收藏+]

非常有意思的 dp,很难想出来吧.  

如果对着图去想,很难有思路,所以可以把图上的问题转化为序列问题.    

我们发现,如果一个点集合法,当且仅当这个点集构成一个不降序列,且其他点都与这个点集形成逆序对.   

令 $f[i]$ 表示由 $1$ ~ $i$ (选 $i$ )构成的合法方案数.    

然后如果不选一个元素,显然这个元素必须和距离该元素最近的被选元素形成逆序对.   

假设我们求完 $f[i]$,要去更新 $j$ ($j>i$),则如果中间元素大于 $a[i]$,则中间元素必须大于 $a[j]$.              

小于的情况同理(只要记住更新最大值位置就行)  

#include <bits/stdc++.h>  
#define N 1009   
#define ll long long    
#define mod 1000000007   
#define setIO(s) freopen(s".in","r",stdin)  
using namespace std;     
int val[N][N],f[N];  
int main() 
{ 
    // setIO("input");      
    int n,m;  
    scanf("%d%d",&n,&m);  
    for(int i=1;i<=m;++i) 
    {
        int x,y;  
        scanf("%d%d",&x,&y),val[x][y]=val[y][x]=1; 
    }    
    f[0]=1;  
    for(int i=0;i<=n;++i) 
    {
        int tmp=0;  
        for(int j=i+1;j<=n+1;++j) 
        {
            if((!tmp||val[tmp][j])&&!val[i][j])  
                (f[j]+=f[i])%=mod,tmp=j;   
        } 
    }  
    printf("%d\n",f[n+1]);  
    return 0; 
}

  

BZOJ4715: 囚人的旋律 dp

原文:https://www.cnblogs.com/guangheli/p/13030336.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!