UVA11766 Racing Car Computer

22 篇文章 0 订阅
  • 解法巧妙的一道题!
  • 题意:n辆赛车,n条信息,第i条信息告诉你编号为i的车前面与后面分别有多少量车,求最少有多少条信息是错误的。
  • 将问题转换一下,等价于最多有多少条信息是对的。
  • 考虑每条信息意味着什么:知道了前后有多少量车,也就知道了这辆车的排名区间以及有多少量车与它并排
  • 每一条合法(对它自己而言)的信息可以确定一个排名区间,如a=1,b=2,n=5,它的排名区间就是[2,3],如果两条信息得出的排名区间有重叠,那么它们就是冲突的,反之不冲突。
  • 我们可以做这样一个处理:每得出一个区间[i,j],就给cnt[i][j]的值+1,当cnt[i][j]的值加到j-i+1的时候不再加,因为这之后表示[i,j]的信息不能与前(j-i+1)条信息共同正确。
  • 这个问题就转换成了一个区间最大不重复覆盖的问题!d[i]表示1~i的最大不重复覆盖值,d[i]=max(d[j]+cnt[j+1][i]) j∈[0,i-1]。
  • 到此这一问题就已解决,考虑这个问题时可以把它拆分成两部分:转换成区间覆盖问题的合理性以及区间覆盖求法上的合理性。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n,dp[1050],cnt[1050][1050],a,b,num;
int main()
{
    while(scanf("%d",&n)&&n)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&b);
            if(a+b<=n-1&&cnt[a+1][n-b]<n-a-b)
            cnt[a+1][n-b]++;
        }
        for(int i=1;i<=n;i++)
        for(int j=0;j<i;j++)
        dp[i]=max(dp[i],dp[j]+cnt[j+1][i]);
        cout<<"Case "<<++num<<": "<<n-dp[n]<<endl;
        memset(dp,0,sizeof(dp));
        memset(cnt,0,sizeof(cnt));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哈希表扁豆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值