[noip2014tg] 飛揚的小鳥

題解:看到題目,二話不說就寫了個爆搜,拿了50,後來優化了一下,改成了記憶化,O(nm^2),慘遭卡常數(寫得太醜了),只有60
dp等以後在寫吧,我太弱了QAQ

爆搜

#include <iostream>
#include <cstdio>
using namespace std;
#define INF 0x3f3f3f3f
const int M=50;
int n,m,k;
int ans=INF,dis;
int x[M],y[M];
int vis[M][M];
struct pipe{
    int p,l,h;
}pi[M];
void init()
{
    cin>>n>>m>>k;
    for(int i=0;i<n;i++)
    scanf("%d%d",&x[i],&y[i]);
    for(int i=1;i<=k;i++){
        scanf("%d%d%d",&pi[i].p,&pi[i].l,&pi[i].h);
        for(int j=1;j<=pi[i].l;j++)
        vis[pi[i].p][j]=1;
        for(int j=m;j>=pi[i].h;j--)
        vis[pi[i].p][j]=1;
    }
}
void dfs(int pos,int high,int tm)
{
    if(high>m) high=m;
    if(high<=0) return ;
    if(vis[pos][high]==1) return ;
    dis=max(dis,pos);
    if(pos==n){
        ans=min(ans,tm);
        return ;
    }
    int tal=0,j=0;
    do
    {
        tal+=x[pos];j++;
        dfs(pos+1,high+tal,tm+j);
    }while(j<=3&&high+tal<=m);
    dfs(pos+1,high-y[pos],tm);
}
void work()
{
    for(int i=1;i<=m;i++)
    dfs(0,i,0);
    if(ans!=INF){
        cout<<"1"<<endl;
        cout<<ans<<endl;
        return ;
    }
    int tot=0;
    for(int i=1;i<=k;i++)
    if(pi[i].p<=dis) tot++;
    cout<<"0"<<endl;
    cout<<tot<<endl;
}
int main()
{
    init();
    work();
}

記憶化

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f3f
const int M=1050;
int n,m,k;
int ans=INF,dis;
int x[M],y[M];
int vis[M][M],f[M][M];
struct pipe{
    int p,l,h;
}pi[M];
void init()
{
    cin>>n>>m>>k;
    for(int i=0;i<n;i++)
    scanf("%d%d",&x[i],&y[i]);
    for(int i=1;i<=k;i++){
        scanf("%d%d%d",&pi[i].p,&pi[i].l,&pi[i].h);
        for(int j=1;j<=pi[i].l;j++)
        vis[pi[i].p][j]=1;
        for(int j=m;j>=pi[i].h;j--)
        vis[pi[i].p][j]=1;
    }
}
int dfs(int pos,int high)
{
    if(high>m) high=m;
    if(high<=0) return INF;
    if(vis[pos][high]==1) return INF;
    if(pos==n) return 0;
    dis=max(dis,pos);
    if(f[pos][high]>0&&f[pos][high]!=INF) return f[pos][high];
    int tal=0,j=0;
    do
    {
        tal+=x[pos];j++;
        f[pos][high]=min(f[pos][high],dfs(pos+1,high+tal)+j);
    }while(high+tal<=m);
    f[pos][high]=min(f[pos][high],dfs(pos+1,high-y[pos]));
    return f[pos][high];
}
void work()
{
    memset(f,0x3f,sizeof(f));
    for(int i=1;i<=m;i++)
    ans=min(ans,dfs(0,i));
    if(ans!=INF){
        cout<<"1"<<endl;
        cout<<ans<<endl;
        return ;
    }
    int tot=0;
    for(int i=1;i<=k;i++)
    if(pi[i].p<=dis) tot++;
    cout<<"0"<<endl;
    cout<<tot<<endl;
}
int main()
{
    init();
    work();
}
發佈了138 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章