NOIP2014Day1T3-飞扬的小鸟


题解:
f [ i ] [ j ] f[i][j] f[i][j]表示横坐标为 i i i时高度为j的最少点击次数。
用正无穷来表示不可能达到这个状态。
于是我们可以分析出状态转移的方式:
上升——完全背包转移方式
下降—— 01 01 01背包转移方式
超过 m m m变为 m m m——特判
C o d e : Code: Code

#include<bits/stdc++.h>
#define ll long long
const int N=1e4+5;
using namespace std;
int n,m,k,vis[N],low[N],high[N],x[N],y[N],f[N][2005];
inline ll read()
{
    ll x=0,f=1;char s=getchar();
    while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
    while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
int main()
{
    n=read(),m=read(),k=read();
    for(int i=1;i<=n;i++)
    {
        x[i]=read(),y[i]=read();
        high[i]=m;low[i]=1;
    }
    for(int i=1;i<=k;i++)
    {
        int p=read(),l=read(),h=read();
        vis[p]=1;low[p]=l+1;high[p]=h-1;
    }
    memset(f,0x3f,sizeof(f));
    for(int i=1;i<=m;i++)f[0][i]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=x[i]+1;j<=m+x[i];j++)
            f[i][j]=min(f[i-1][j-x[i]]+1,f[i][j-x[i]]+1);
        for(int j=m+1;j<=m+x[i];j++)f[i][m]=min(f[i][m],f[i][j]);
        for(int j=1;j<=m-y[i];j++)f[i][j]=min(f[i][j],f[i-1][j+y[i]]);
        for(int j=1;j<low[i];j++)f[i][j]=f[0][0];
        for(int j=high[i]+1;j<=m;++j)f[i][j]=f[0][0];
    }
    int ans=f[0][0];
    for(int j=1;j<=m;j++)ans=min(ans,f[n][j]);
    if(ans<f[0][0])printf("1\n%d\n",ans);else
    {
        int i,j;
    	for(i=n;i>=1;i--)
        {
            for(j=1;j<=m;j++)
                if(f[i][j]<f[0][0])break;
            if(j<=m)break;
        }
        ans=0;
        for(int j=1;j<=i;j++)if(vis[j])ans++;
        printf("0\n%d\n",ans);
    }
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack-Oran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值