Uva 11008 - Antimatter Ray Clearcutting 状态压缩

本文介绍了一个有趣的状压DP算法问题:通过射击砍掉指定数量的树。利用二进制状态压缩来记录每棵树的状态,并通过动态规划算法求解最小射击次数。文章详细解释了解题思路并提供了完整的C++代码实现。

今天可以说弄了好久,之前没怎么接触状压,不过今天看到一题,其实懂了意思,经感觉有点有趣。。

题意:给出n棵树的位置,要求一个人可以站在任意位置(我以为是固定位置,后面看样列发现是任意的),以任意方用枪打掉m棵树,求最少打的枪数

思路:用二进制表示所有数的状态,如4棵树1111,为0 证明数被砍掉,为1没被砍掉,所以只要计数1的个数少于等于n-m即可  用s[i][j]表示以i,j为两点确定的一条直线,它的值的二进制表示也映射出了这条线上的树的棵树极其状态

ff[S]表示在状态S下最少需要几枪

代码:

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#define lson l,mid,num<<1
#define rson mid+1,r,num<<1|1
using namespace std;
const int M=100005;
#define inf 0x7fffffff
#define M 20
#define Max 1<<18
int x[M],y[M];
int s[M][M];//有第i个点和第j个点连接成的直线
int ff[Max];//表示这个状态最少需要多少把枪
int n,m,c;
int dp(int S)
{
    int sum=0,ans;
    if(ff[S]!=-1)return ff[S];
    for(int i=0; i<n; i++)
        if(S&(1<<i))sum++;//存在这个点
    if(sum<=c)return ff[S]=0;
    if(sum==1)return ff[S]=1;//只存在一个点
    ff[S]=inf;
    for(int i=0; i<n; i++)
    {
        if((1<<i) & S)
            for(int j=i+1; j<n; j++)
                if((1<<j) & S)
                {
                    ans=dp(S&(~s[i][j]))+1;//一枪打掉这条直线上的点
                    if(ans <ff[S])
                        ff[S]=ans;
                }
    }
    return ff[S];
}
void solve(int g)
{
    int ans;
    memset(s,0,sizeof(s));
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(i==j)continue;
            for(int k=n-1; k>=0; k--)
            {
                s[i][j]<<=1;
                if((y[j]-y[i]) *(x[k]-x[i])==(y[k]-y[i])*(x[j]-x[i]))
                    s[i][j]++;
            }
        }
    }
    c=n-m;
    memset(ff,-1,sizeof(ff));
    ans=dp((1<<n)-1);//刚开始有2^n-1棵树(状态)
    printf("Case #%d:\n%d\n",g,ans);
}
int main()
{
    int t,g=0;
    scanf("%d",&t);
    for(int i=1; i<=t; i++)
    {
        g++;
        scanf("%d%d",&n,&m);
        for(int i=0; i<n; i++)
            scanf("%d%d",&x[i],&y[i]);

        solve(g);
        if(g!=t)
            printf("\n");
    }
    return 0;
}


混合动力汽车(HEV)模型的Simscape模型(Matlab代码、Simulink仿真实现)内容概要:本文档介绍了一个混合动力汽车(HEV)的Simscape模型,该模型通过Matlab代码和Simulink仿真工具实现,旨在对混合动力汽车的动力系统进行建模与仿真分析。模型涵盖了发动机、电机、电池、传动系统等关键部件,能够模拟车辆在不同工况下的能量流动与控制策略,适用于动力系统设计、能耗优化及控制算法验证等研究方向。文档还提及该资源属于一个涵盖多个科研领域的MATLAB仿真资源包,涉及电力系统、机器学习、路径规划、信号处理等多个技术方向,配套提供网盘下载链接,便于用户获取完整资源。; 适合人群:具备Matlab/Simulink使用基础的高校研究生、科研人员及从事新能源汽车系统仿真的工程技术人员。; 使用场景及目标:①开展混合动力汽车能量管理策略的研究与仿真验证;②学习基于Simscape的物理系统建模方法;③作为教学案例用于车辆工程或自动化相关课程的实践环节;④与其他优化算法(如智能优化、强化学习)结合,实现控制策略的优化设计。; 阅读建议:建议使用者先熟悉Matlab/Simulink及Simscape基础操作,结合文档中的模型结构逐步理解各模块功能,可在此基础上修改参数或替换控制算法以满足具体研究需求,同时推荐访问提供的网盘链接获取完整代码与示例文件以便深入学习与调试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值