HDU 6092 Rikka with Subset 思維 遞推
阿新 • • 發佈:2017-08-08
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 );View Codefor( 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; }
思考: 這道題一開始我就沒敢向遞推那裏想.....因為我覺得判定哪個元素對哪個自己做出貢獻是不能夠的....但是題給出了這個和的已知條件.....哎, 自己太狹隘了.,.,....昨天那道DP還是沒有A, 現在A掉
HDU 6092 Rikka with Subset 思維 遞推