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));
}
posted @ 2018-10-10 23:42  Katoumegumi  阅读(74)  评论(0编辑  收藏  举报
返回顶部