1. 程式人生 > >【51Nod1779】逆序對統計

【51Nod1779】逆序對統計

lyk最近計劃按順序做n道題目,每道題目都分為很多分數檔次,lyk覺得這些題太簡單了,於是它想到了一個好玩的遊戲。
lyk決定將每道題目做出其中的某個分數,使得這n道題目的逆序對個數最多。
為了方便,假設共有m個分數檔次,並且會給m個分數檔次分配一個題目編號,表示該題目會出現這個分數檔次。
題目保證每道題都存在至少一個分數檔次。(例如樣例中5道題目的分數分別是5,6,3,4,7,共有4個逆序對)
Input
第一行兩個數n,m(n<=20,m<=100)。
接下來m行,每行一個數ai,表示第ai道題目可能會有i這個分數的檔次。
Output
一個數表示最多逆序對個數。
Input示例
5 7
1
2
3
4
1
2
5
Output示例
4

題解
問題可以對應為在m個分值中選擇n個,組成最大逆序對,然後就是裸題了。

程式碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<set>
#include<ctime>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#define mod 1000000007 
#define ll long long  
#define inf 1e9 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,dp[1<<20]; int main() { n=read();m=read(); int
all=1<<n; for (int j=1;j<all;j++) dp[j]=-inf; for (int i=1;i<=m;i++) { int x=read();x--; for (int j=0;j<all;j++) { if (dp[j]==-inf) continue; if (j&(1<<x)) continue; int sum=0; for (int k=x+1;k<n;k++) if (j&(1<<k)) sum++; dp[j|(1<<x)]=max(dp[j]+sum,dp[j|(1<<x)]); } } printf("%d",dp[all-1]); return 0; }