D. Unmerge( 找规律 + 01背包 )

D. Unmerge( 找规律 + 01背包 )

题目链接:https://codeforces.com/contest/1382/problem/D

题意:对于一个长度为2n的排列(排列是指一个没有重复元素,有顺序的正整数集合)(保证n为正整数),问:是否可以把这个排列分解成两个长度为n的队列,使得每次取出两个队列的较小队首后,恰好能还原成原来的排列( 即把归并排序后的序列拆成原来的两个序列,要求长度都是n )。如果可以,输出YES,否则输出NO

思路:思考的时候,发现一个问题:对于某一个极大值来讲,从它开始到下一个比它大的值必须要在一个队列里连续排列。

就拿这组样例说话:

3 2 6 1 5 7 8 4

如果3在第一个队列里了,那么2肯定也在同一个队列里并且紧随其后,才可能保证3,2连续被弹出,否则,如果3在第一个队列,2在第二个队列,那么一开始弹出的就不是3而是2,如果2在6后面,在6没有被弹出之前也不可能轮到2,构造均宣布失败。

那么,这么一个数列就被我们分成了若干个小段,每段由一个段首极大值和在它后面的若干个较小值组成。比如上面的例子,最终我们就将其分成了如下的段落:

[3,2],[6,1,5],[7],[8,4]

到了这里就容易想到:如果我们能从这些长度不同的段落中挑出任意段,使之恰好能塞满长度n的一个排列,那么我们就构造成功了。(题目不需要我们考虑段与段之间的顺序问题)比如上面的样例答案就是:

[3,2,8,4],[6,1,5,7]

所以好像是个背包问题?是恰好装满01背包。

代码:

#include<bits/stdc++.h>

using namespace std;

int price[4005],weight[4005];
int dp[4005],a[4005],n;

int main()
{
    int T;cin>>T;
    while ( T-- ) {
        cin>>n;
        for ( int i=1; i<=2*n; i++ ) scanf("%d",&a[i]);a[2*n+1]=0x3f3f3f3f;
        int cnt=0,mx=0,tot=0;
        for ( int i=1; i<=2*n+1; i++ ) {
            if ( i==1 ) {
                mx = a[i];
                cnt = 1;
                continue;
            }
            if ( a[i]<mx ) {
                cnt++;
            }
            else {
                price[tot] = cnt;
                weight[tot++] = cnt;
                mx = a[i];cnt=1;
            }
        }
        memset(dp,-0x3f3f3f3f,sizeof(dp));
        dp[0] = 0;
        for ( int i=0; i<tot; i++ ) {
            for ( int j=n; j>=1; j-- ) {
                if ( j>=weight[i] ) {
                    dp[j] = max( dp[j], dp[j-weight[i]] + price[i] );
                }
            }
        }
        if ( dp[n]>0 ) cout << "yes" << endl;
        else cout <<"no"<<endl;
    }

    return 0;
}

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,'DataFrame'对象没有'unmerge_cells'属性的错误是由于尝试在DataFrame对象上调用'unmerge_cells'方法而引起的。这个错误可以通过以下方法进行修复: 1. 检查pandas库的版本:确保你正在使用的是最新版本的pandas库。你可以使用以下命令检查版本: ```python import pandas as pd print(pd.__version__) ``` 如果你的版本较旧,可以考虑升级到最新版本。 2. 检查数据类型:确保你的数据是正确的类型。如果你的数据不是DataFrame对象,而是其他类型的对象(如Series),则无法调用'unmerge_cells'方法。你可以使用以下命令检查数据类型: ```python print(type(data)) ``` 如果数据类型不是DataFrame,请确保将数据正确加载为DataFrame对象。 3. 检查方法名称:确认你是否正确地使用了'unmerge_cells'方法。在pandas库中,并没有名为'unmerge_cells'的方法。如果你想要取消合并单元格,可以使用ExcelWriter对象的'unmerge_cells'方法。以下是一个示例: ```python import pandas as pd # 创建ExcelWriter对象 writer = pd.ExcelWriter('output.xlsx') # 将DataFrame写入Excel文件 data.to_excel(writer, sheet_name='Sheet1') # 获取ExcelWriter对象的底层Workbook对象 workbook = writer.book # 获取Sheet对象 sheet = workbook.get_sheet_by_name('Sheet1') # 取消合并单元格 sheet.unmerge_cells('A1:B2') # 保存Excel文件 writer.save() ``` 在上面的示例中,我们首先创建了一个ExcelWriter对象,然后将DataFrame写入Excel文件。接下来,我们获取ExcelWriter对象的底层Workbook对象,并使用它来获取Sheet对象。最后,我们使用Sheet对象的'unmerge_cells'方法取消合并单元格。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值