ccf

string的用法

https://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html

vector

https://www.cnblogs.com/mengfanrong/p/3770971.html

类型转换

https://blog.csdn.net/xiaoquantouer/article/details/51746476

导弹拦截

#include <iostream>
#include<bits/stdc++.h>
#define MAX 100100
int f[MAX];//f[i]表示以i结尾的最长非升子序列的长度
int h[MAX];
int n;
int b[MAX];//b[n]长度为n的非升子序列的结尾值,即最大值
using namespace std;
void init()
{
    memset(f,0,sizeof(f));
    memset(b,0,sizeof(b));
    for(int i = 0;i < n;i++) f[i] = 1;
}
int lbs1()//最长非升子序列
{
    int ans = 0;
    for(int i = 1;i < n;i++)//求 f[i]
    {
        int ma = 1;
        for(int j = 0;j < i;j++)
        {
            if(h[i] <= h[j])
                ma = max(ma,f[j]+1);
        }
        f[i] = ma;
        ans = max(ans,ma);
    }
    return ans;
}
int bina2(int k,int num)//二分法,b上升序列,返回大于或等于num的最小值的下标
//若只是返回大于num的最小值的下标 那么当b数组为2 4 8 9 14 而num为8时,将返回9的下标,并将9改为8
//b数组就成了2 4 8 8 14,而此问题是最长升序,而非最长非递减
{
    if(num < b[1])
        return 1;
    int low = 1,high = k;
    int mid;
//    while(low < high)
//    {
//        mid = (low+high)/2;
//        if(b[mid] >= num)
//            high = mid;
//        else
//            low = mid+1;
//    }
//    return low;
    for(;low < high-1;)
    {
        mid = (low+high)/2;
        if(b[mid]<num)//将<= 改为 <,
        {
            low = mid;
        }
        else
        {
            high = mid;
        }
    }
    return high;
}
int lbs4()
{
    int k = 1;
    b[1] = h[0];
    for(int i = 1;i < n;i++)
    {
        if(h[i] > b[k])
        {
            b[++k] = h[i];
        }
        else
        {
            b[bina2(k,h[i])] = h[i];
        }
    }
    return k;
}
int lbs3()//最长上升子序列
{
    int ans = 0;
    for(int i = 1;i < n;i++)//求 f[i]
    {
        int ma = 1;
        for(int j = 0;j < i;j++)
        {
            if(h[i] > h[j])
                ma = max(ma,f[j]+1);
        }
        f[i] = ma;
        ans = max(ans,ma);
    }
    return ans;
}

int binary(int b[],int k,int num)//二分法,b非升序列,返回小于num的最大值的下标
{
    if(num > b[1])
        return 1;
    int mid = 0;
    int low = 1,high = k;
    for(;low < high-1;)
    {
        mid = (low+high)/2;
        if(b[mid]>=num)
        {
            low = mid;
        }
        else
        {
            high = mid;
        }
    }
    return high;
}
int lbs2()
{
    int k=1;
    b[1] = h[0];
    for(int i = 1;i < n;i++)
    {
        if(h[i] <= b[k])
        {
            b[++k] = h[i];
        }
        else
        {
            b[binary(b,k,h[i])] = h[i];
        }
    }
    return k;
}
int main()
{
//    cin >> n;
//    for(int i = 0;i < n;i++)
//    {
//        cin >> h[i];
//    }
    n = 0;
    while(scanf("%d",&h[n++])!=EOF);
    n--;
    init();
    int ans1,ans2;
    ans1 = lbs2();
    init();
    ans2 = lbs4();
    cout << ans1 << endl << ans2 << endl;

}

嵌套矩形

#include<bits/stdc++.h>
#define MAX 300
typedef struct{
    int length;
    int width;
}rectangle;
rectangle rec[MAX];
int G[MAX][MAX] = {0};//G[i][j] 表示j结点到i结点有一个有向边,rec[i]可包含rec[j]
int f[MAX] = {0};//f[i]以i为结尾的最长路径,即rec[i]最多能装多少个矩形
using namespace std;
int n;
void createGraph()
{
    for(int i = 0;i < n;i++)
        for(int j = 0;j < n;j++)
        {
            if(rec[i].length > rec[j].length && rec[i].width > rec[j].width)
            {
                G[i][j] = 1;
            }
            else
                G[i][j] = 0;
        }
}
int dp(int i)
{
    if(f[i]!=0) return f[i];
    else f[i]=1;
    for(int j = 0;j < n;j++)
    {
        if(G[i][j]==1)
        {
            int tmp = dp(j);
            f[i]=max(f[i],tmp+1);
        }
    }
    return f[i];
}
int main()
{
    int a,b,ans = 0;
    cin >> n;
    for(int i = 0;i < n;i++)
    {
        cin >> a >> b;
        rec[i].length = a>b ? a:b; //长大于宽
        rec[i].width = a<b?a:b;
    }
    createGraph();
    for(int i = 0;i <n;i++)
        f[i]=0;
    for(int i = 0;i < n;i++)
    {
        int tmp = dp(i);
        ans = ans>tmp?ans:tmp;
    }
    cout << ans <<endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值