2018.10.10 练习赛 状态压缩专练

T1 防守马克

题解:

贪心,用(力量+重量)排序然后\(dfs\);

\(code\):

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
    int h,w,s;
}a[30];
int n,h;
bool c[30];
long long ans=-1;
bool cmp(const node &x,const node &y)
{
    return x.w+x.s>y.w+y.s;
}
void dfs(int x,int ch)
{
    c[x]=ch;
    if(x==n)
    {
        long long tmp=1e9,len=0;
        for(int i=1;i<=n;i++)
        if(c[i])
        {
            len+=a[i].h;
            long long sum=0;
            for(int j=i+1;j<=n;j++)
            sum+=c[j]?a[j].w:0;
            tmp=min(tmp,a[i].s-sum);
        }
    if(len>=h)ans=max(ans,tmp);return;}
    dfs(x+1,1);
    dfs(x+1,0);
}
int main()
{
    scanf("%d%d",&n,&h);
    for(int i=1;i<=n;i++)
    scanf("%d%d%d",&a[i].h,&a[i].w,&a[i].s);
    sort(a+1,a+n+1,cmp);
    dfs(0,0);

    if(ans==-1) printf("Mark is too tall\n");
    else printf("%lld",ans);
}

T2 王国危机

题解:

\(dfs\)二进制状压记录状态,标记状态

\(code:\)

#include <cmath> 
#include <cstdio> 
#include <cstring> 
#include <iostream> 
#include <algorithm> 
#include<ctype.h> 
#define bin(x) (1<<x)
#define inf 1e9+9 
#define ll long long 
using namespace std; 

char buf[1<<20],*p1,*p2; 
inline char gc() 
{ 
//    return getchar(); 
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++; 
} 

template<typename T> 
inline void read(T &x) 
{ 
    char tt; 
    bool flag=0;
    while(!isdigit(tt=gc())&&tt!='-');
    tt=='-'?(flag=1,x=0):(x=tt-'0'); 
    while(isdigit(tt=gc())) x=x*10+tt-'0'; 
    if(flag) x=-x;
} 

int n,tot;
int a[25][25];
int w[25],ans;
bool book[1<<21];

void dfs(int s,int rest) {
    if(book[s]) return;
    book[s]=1;
    if (rest==1)
    { 
        ans|=s; 
        return;
    }
    for(int i=0;i<n;i++)
        if((bin(i)&s)&&w[i+1]>0) {
            for(int j=1;j<=n;j++)w[j]-=a[j][i+1];
            dfs(s^bin(i),rest-1);
            for(int j=1;j<=n;j++)w[j]+=a[j][i+1];
        }
}

int t;
int main()
{
//  freopen("1.txt","w",stdout);
    read(t);
    while(t--)
    {
        read(n);
        for(int i=1;i<=n;i++)
        {
            w[i]=0;
            for(int j=1;j<=n;j++)
            read(a[i][j]),w[i]+=a[i][j];        
        }
        
        ans=0;
        tot=bin(n)-1;
        for(int i=0;i<=tot;i++) book[i]=0;
        dfs(tot,n);
        bool flag=0;
        for(int i=0;i<n;i++)
        if(bin(i)&ans) 
        printf("%d ",i+1),flag=1;
        if (!flag) putchar('0');
        putchar(10);
    }
}

T3 奇怪的道路

题解:

同原先\(THH\)学长出的数数\(......\)

\(code:\)

#include<stdio.h>
#include<string.h>
#define ll long long
#define mod 1000000007

ll f[31][31][31][1<<9];
ll n,m,lim;

void inc(ll &a,ll b) {
    a+=b;
    a-=a<mod?0:mod;
}

ll dfs(ll u,ll l,ll v,ll s) {
    if(l==0) return s==0;
    if(u==1) return 0;
    if(f[u][l][v][s]!=-1) return f[u][l][v][s];
    ll ans=0;
    inc(ans,dfs(u,l-1,v,s^1^(1<<(u-v))));
    if(v>1&&u-v+1<=lim) inc(ans,dfs(u,l,v-1,s));
    else if(!(s&1)) inc(ans,dfs(u-1,l,u-2,s>>1));
    return f[u][l][v][s]=ans;
}

int main() {
    memset(f,-1,sizeof(f));
    scanf("%lld%lld%lld",&n,&m,&lim);
    printf("%lld",dfs(n,m,n-1,0));
}

猜你喜欢

转载自www.cnblogs.com/KatouKatou/p/9769967.html