1. 程式人生 > >HDU 6092 Rikka with Subset 思維 遞推

HDU 6092 Rikka with Subset 思維 遞推

display 第一個 代碼 play int spa pid close 說明

  題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=6092

  題目描述: 給你一個集合的所有子集各個和, 讓你找到這個集合, 輸出字典序最小

  解題思路: 下標0上的數字肯定是1, 所以從下標為1的開始向後, 第一個不為零的數的下標肯定是集合中的一個數而且是最小的數......同時將這個數減減, 記住這個下標為cur(所以這個集合應該是唯一的?我沒嚴格證明, 但是每一步取得值肯定都是唯一的啊, 而且從小到大)這樣我們向後面偏移cur個單位, 如果兩個數都不為0, 就說明cur這個數肯定做出了貢獻(cur此時就最小的數, 所以不可能會有數兒組合取來等於cur), 這樣篩了N遍就可以篩出來了

  代碼:

技術分享
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

const int maxm = 1100002;
int a[maxm];
int m;
int ans[maxm];

int main(){
    int t;
    scanf( "%d", &t );
    while( t-- ) {
        int n;
        scanf( "%d%d", &n, &m );
        
for( int i = 0; i <= m; i++ ) { scanf( "%d", a+i ); } a[0] = 0; for( int i = 0; i < n; i++ ) { int j; for( j = 0; j <= m; j++ ) { if( a[j] ) break; } a[j]--; ans[i] = j; for
( int k = j; k <= m; k++ ) { if( k+j <= m && a[k] && a[k+j] ) { a[k+j] -= a[k]; } } } for( int i = 0; i < n; i++ ) { i == 0 ? printf( "%d", ans[i] ) : printf( " %d", ans[i] ); } printf( "\n" ); } return 0; }
View Code

  思考: 這道題一開始我就沒敢向遞推那裏想.....因為我覺得判定哪個元素對哪個自己做出貢獻是不能夠的....但是題給出了這個和的已知條件.....哎, 自己太狹隘了.,.,....昨天那道DP還是沒有A, 現在A掉

HDU 6092 Rikka with Subset 思維 遞推