复制代码

LuoGU 线性DP

P1091 合唱队形

看一下题解吧,你好i需要正反搜一下lcs ,然后合并

#include<bits/stdc++.h>
using namespace std;
#define LOACL  freopen("in","r",stdin);\
            freopen("out","w",stdout); 

const int  inf = 987654321;
const int sz = 1e6 + 5;
const int mod = 1e9 + 7;
const int sqrtn = 300; 

#define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
#define f(i,l,r) for(int i=(int)l;i<=(int)r;++i)
#define g(i,l,r) for(int i=(int)l;i>=(int)r;--i)
#define CLR(arr,val) memset(arr,val,sizeof(arr)) 
typedef long long ll; 
int n,a[sz],dp[2][sz],ans;
int main()
{
    LOACL
    cin>>n;
    f(i,1,n)cin>>a[i];

    f(i,1,n)f(j,0,i-1)if(a[i]>a[j])dp[0][i]=max(dp[0][i],dp[0][j]+1); 
    g(i,n,1)g(j,n+1,i+1) if(a[i]>a[j]) dp[1][i]=max(dp[1][i],dp[1][j]+1);
    f(i,1,n) ans=max(ans,dp[0][i]+dp[1][i]-1);
    cout<<n-ans<<endl;
    return 0;
}
View Code

 

P1280 尼克的任务

倒着搜索寻找是否能休息 

转移方程 : f[i]=f[i+1]+1;

     d[i]=f[i+s];  i 时间内有任务 需要向后找状态

#include<bits/stdc++.h>
using namespace std;
#define LOACL  freopen("in","r",stdin);\
            freopen("out","w",stdout); 

const int  inf = 987654321;
const int sz = 1e6 + 5;
const int mod = 1e9 + 7;
const int sqrtn = 300; 

#define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
#define f(i,l,r) for(int i=(int)l;i<=(int)r;++i)
#define g(i,l,r) for(int i=(int)l;i>=(int)r;--i)
#define CLR(arr,val) memset(arr,val,sizeof(arr)) 
typedef long long ll; 
ll n,m,num=1;
ll sum[sz],f[sz];
struct node
{
    ll l,r;
}e[sz];
bool cmp(node l,node r)
{
    return l.l>r.l;
}
int main()
{
    LOACL
    cin>>n>>m;
    f(i,1,m)
    {
        cin>>e[i].l>>e[i].r ;
        sum[e[i].l]++;
    }
    sort(e+1,e+m+1,cmp);
    g(i,n,1)
    {
        if(sum[i]==0)
            f[i]=f[i+1]+1;
        else 
        {
            f(j,1,sum[i])
            {
            if(f[i]<f[i+e[num].r])
                 f[i]=f[i+e[num].r];     
             num++;
            }
        } 
         
    }
    cout<<f[1]<<endl; 
    return 0;
}
View Code

 

P1880 [NOI1995]石子合并

处理一下 前缀和 因为是一个环 所以2倍

 状态转移 dp[i][j]=max/min(dp[i][k]+dp[k+1][j]+sum(i,j));

 #include<bits/stdc++.h>
 using namespace std;
 #define LOACL  freopen("in","r",stdin);\
       freopen("out","w",stdout); 
 
 const int  inf = 987654321;
 const int sz = 1e6 + 5;
 const int mod = 1e9 + 7;
 const int sqrtn = 600; 
 
 #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
 #define f(i,l,r) for(int i=(int)l;i<=(int)r;++i)
 #define g(i,l,r) for(int i=(int)l;i>=(int)r;--i)
 #define CLR(arr,val) memset(arr,val,sizeof(arr)) 
 typedef long long ll; 
 int n,a[300],f1[300][300],f2[300][300],sum[300];
 int main()
 {
   LOACL
    cin>>n;
    f(i,1,n)
    {
      cin>>a[i];
      a[i+n]=a[i];
    }
    f(i,1,n<<1)
    {
      sum[i]=sum[i-1]+a[i];
    }

    g(i,n<<1,1)
    {
      f(j,i+1,min(n+n,i+n-1))
      {
        f2[i][j]=inf;
        f(k,i,j-1)
        {
             f1[i][j]=max(f1[i][j],f1[i][k]+f1[k+1][j]+sum[j]-sum[i-1]);
             f2[i][j]=min(f2[i][j],f2[i][k]+f2[k+1][j]+sum[j]-sum[i-1]);
        }
      }
    }
   // f2 min 
    int maxn = -inf,minn = inf;
    f(i,1,n)
    {
      maxn =max(maxn,f1[i][i+n-1]);
      minn =min(minn,f2[i][i+n-1]); 
    }
      cout  <<minn<<endl;

    cout  <<maxn<<endl;
  
   return 0;
 }
View Code

 

posted @ 2018-03-16 12:07  pg633  阅读(112)  评论(0编辑  收藏  举报