程序設計思維與實踐 Week3 作業

在這裏插入圖片描述
在這裏插入圖片描述
思路:要在n個數中選擇K個,並且讓和爲S,n<=16,所以dfs,記一下當前選到第幾個,選了幾個,和是啥就ok。

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,k,a[101],t,ans;
void solve(int x,int y,int sum)
{

    if(y==k){if(sum==m) ans++;return ;}
    if(x==n+1||sum>m) return ;
    solve(x+1,y+1,sum+a[x]);
    solve(x+1,y,sum);
    return ;
}
int main()
{
    scanf("%d",&t);
    while (t--)
    {
        ans=0;
        scanf("%d%d%d",&n,&k,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        solve(1,0,0);
        printf("%d\n",ans);
    }
    return 0;
}

總結:裸的dfs,穩點寫,多造點樣例
在這裏插入圖片描述
思路: 貪心,先右端點升序,再左端點降序,貪心的選每個線段的右端點即可,左端點降序是爲了處理線段包含的情況。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,k,a[101],t,ans;
struct da{int l,r;}s[1001];
int cmp(const da &x,const da &y)
{
    return x.r!=y.r?x.r<y.r:x.l>y.l;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&s[i].l,&s[i].r);
    }
    sort(s+1,s+n+1,cmp);
    int x=-1;
    for(int i=1;i<=n;i++)
    {
        if(s[i].l<=x&&x<=s[i].r) continue;
        else ans++,x=s[i].r;
    }
    printf("%d",ans);
    return 0;
}

總結:線段相關的題目要記得考慮包含的情況。
在這裏插入圖片描述
思路:貪心,先左端點升序,再右端點降序,也是爲了考慮線段包含的情況,一開始先把肯定無解的情況去掉,然後每次選擇一個點,然後選出一個包含這個單的集合,求有多少個集合即可。選點的時候我們貪心的選擇每個線段的右端點。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,k,t,ans;
bool flag=true;
struct da{int l,r;}s[100001];
int cmp(const da &x,const da &y)
{
    return x.l!=y.l?x.l<y.l:x.r>y.r;
}
int main()
{
    while(scanf("%d%d",&n,&t)!=EOF)
    {
        ans=1;flag=true;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&s[i].l,&s[i].r);
        }
        sort(s+1,s+n+1,cmp);
        if(s[1].l!=1) flag=false;
        bool flag2= false;

        for(int i=1;i<=n;i++)
        {
            if(s[i].r>=t) flag2=true;
        }
        if(!flag2) flag= false;
        int i=1;
        int x=s[1].r,y=0;
        while(i<n)
        {
            if(x>=t) break;
            int j=i+1;
            while((s[j].l<=x||s[j].l==x+1)&&j<=n) y=max(y,s[j].r),j++;
            j--;
            if(j==i||s[j].r<=x) {flag=false;break;}
            else if(y>x) ans++,x=y;
            i=j;
        }
        if(flag) printf("%d\n",ans);
        else printf("-1\n");
    }
    return 0;
}

總結:要多考慮特殊情況,被卡的很難受。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章