您的位置:首页 > 其它

[noip2014tg] 飞扬的小鸟

2016-11-11 21:02 337 查看
题解:看到题目,二话不说就写了个爆搜,拿了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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: