CF6D Lizards and Basements 2(暴力dfs || dp)

题目链接:

Lizards and Basements 2 - 洛谷

思路:

看到数据不大,直接枚举每个位置的攻击次数即可。注意左边的弓箭手必须打死,另外,到n-1位置时,还必须把n-1和n都打死。

这题还有dp的做法,不过我没想出来,可能之后会补充上。

代码:

#include <bits/stdc++.h>
using namespace std;
int n, a, b;
int arr[11];
int minn = INT_MAX; //最少攻击次数
vector<int> tmp, ans; //临时攻击日志,最优攻击日志

void dfs(int cur, int sum){ //攻击位置,总的攻击次数
    if(sum >= minn) return; //剪枝
    if(cur == n) {minn = sum; ans = tmp; return;}
    for(int i=0; i<=16; i++){
        if(arr[cur-1]-i*b>=0) continue;
        if(cur==n-1 && (arr[cur]-i*a>=0 || arr[cur+1]-i*b>=0)) continue;
        arr[cur] -= i*a, arr[cur-1]-=i*b, arr[cur+1]-=i*b; //打cur位置i次
        for(int j=0; j<i; j++) tmp.push_back(cur); //储存
        dfs(cur+1, sum+i);
        arr[cur] += i*a, arr[cur-1]+=i*b, arr[cur+1]+=i*b; //回溯
        for(int j=0; j<i; j++) tmp.pop_back();
    }
}
int main(){
    cin >> n >> a >> b;
    for(int i=1; i<=n; i++) cin >> arr[i];
    dfs(2, 0);
    cout << minn << '\n';
    for(int i : ans) cout << i << ' ';
}

-------------------------------------------------------------------------------------------------------------------------

补充:dp法的代码(是别的题解上的)

设 f[i][j][k]​ 表示到考虑第 i 个人,前 i-1 个人已经全被打死,其中第 i-1 个人受到了 j 个火球,第 i 个人受到了 k 个火球的最小使用火球数量。

#include <bits/stdc++.h>
using namespace std;
int f[15][20][20],n,hp[15],a,b,ans=2147483647,fr[20][20][20];
int main(){
	scanf("%d%d%d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	scanf("%d",&hp[i]);
	memset(f,63,sizeof(f)); //memset为inf(次数不可能超过63)
	for(int i=(hp[1]/b+1);i<=16;i++)
	f[2][0][i]=i; //初始化,一开始只打了第二个人(并且注意必须打死第一个才能初始化)
	for(int i=3;i<=n;i++) //i-1表示中间的人
	for(int j=0;j<=16;j++) //左边打的次数
	for(int k=0;k<=16;k++) //中间打的次数
	for(int l=0;l<=16;l++) //右边打的次数
	if((j+l)*b+k*a>hp[i-1]){ //中间的人能打死
		if(f[i][k][l]>f[i-1][j][k]+l){ //f[i-1][j][k]+l表示打死前i-1个人总共需要的攻击次数,把它的最小值存到f[i][j][k]
			f[i][k][l]=f[i-1][j][k]+l;
			fr[i][k][l]=j; //存储前一个人被打次数
		}
	}
	int rec=2147483647,ans=2147483647,p1,p2;
	for(int i=0;i<=16;i++){
		for(int j=0;j<=16;j++){
			int now=hp[n-1]-i*b-j*a>=0?(hp[n-1]-i*b-j*a)/a+1:0;
			if(j*b<=hp[n])now=(hp[n]-b*j)/b+1;
			if(f[n-1][i][j]+now<ans){
				ans=now+f[n-1][i][j];
				rec=now;
				p1=i;
				p2=j;
			}
		}
	}
	printf("%d\n",ans);
	for(int i=1;i<=rec;i++)
	printf("%d ",n-1);
	int now=n-1,rp1,rp2;
	while((now-1)){
		rp1=p1,rp2=p2;
		p1=fr[now][rp1][rp2];
		p2=rp1;
		for(int i=1;i<=rp2;i++)
		printf("%d ",now);
		now--;
	}
	printf("\n");
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设你已经有一个包含不同蜥蜴样本的数据集,其中每个样本都有多个变量。以下是一种可能的实现方法: 1. 加载数据集并提取与蜥蜴种类相关的变量。假设这些变量存储在名为 `species` 的列向量中,而其他变量存储在名为 `features` 的矩阵中。 ``` data = load('lizards.mat'); species = data.species; features = data.features; ``` 2. 确定第五种蜥蜴的标签。假设第五种蜥蜴的标签为 `5`。 ``` label = 5; ``` 3. 计算每个变量对的差异性,以确定哪两个变量对最能够区分第五种蜥蜴和其他蜥蜴。可以使用 t-检验、方差分析或其他统计方法计算两个变量之间的显著性差异。以下是使用 t-检验进行计算的示例代码: ``` p_values = zeros(size(features, 2)); for i = 1:size(features, 2) for j = i+1:size(features, 2) [~, p_values(i,j)] = ttest2(features(species==label,i), features(species~=label,j)); end end ``` 4. 找出差异性最大的变量对。可以使用 `max` 函数找出 `p_values` 矩阵中的最大值,然后使用 `find` 函数确定该最大值所在的位置。 ``` [max_value, max_index] = max(p_values(:)); [row, col] = find(p_values == max_value); ``` 5. 输出结果。 ``` fprintf('The most discriminative variable pair is %d and %d.\n', row, col); ``` 注意,这只是一种可能的实现方法。实际上,确定哪些变量对最能够区分蜥蜴种类是一个复杂的问题,需要根据具体情况进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值